diff --git a/.circleci/config.yml b/.circleci/config.yml
index aa6a1089..cee9f090 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -16,7 +16,7 @@ jobs:
- checkout
- restore_cache:
keys:
- - v2-pkg-cache
+ - v3-pkg-cache
- run:
name: tools
command: |
@@ -38,11 +38,11 @@ jobs:
- bin
- profiles
- save_cache:
- key: v2-pkg-cache
+ key: v3-pkg-cache
paths:
- /go/pkg
- save_cache:
- key: v2-tree-{{ .Environment.CIRCLE_SHA1 }}
+ key: v3-tree-{{ .Environment.CIRCLE_SHA1 }}
paths:
- /go/src/github.com/tendermint/tendermint
@@ -52,9 +52,9 @@ jobs:
- attach_workspace:
at: /tmp/workspace
- restore_cache:
- key: v2-pkg-cache
+ key: v3-pkg-cache
- restore_cache:
- key: v2-tree-{{ .Environment.CIRCLE_SHA1 }}
+ key: v3-tree-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: slate docs
command: |
@@ -68,9 +68,9 @@ jobs:
- attach_workspace:
at: /tmp/workspace
- restore_cache:
- key: v2-pkg-cache
+ key: v3-pkg-cache
- restore_cache:
- key: v2-tree-{{ .Environment.CIRCLE_SHA1 }}
+ key: v3-tree-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: metalinter
command: |
@@ -84,9 +84,9 @@ jobs:
- attach_workspace:
at: /tmp/workspace
- restore_cache:
- key: v2-pkg-cache
+ key: v3-pkg-cache
- restore_cache:
- key: v2-tree-{{ .Environment.CIRCLE_SHA1 }}
+ key: v3-tree-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: Run abci apps tests
command: |
@@ -101,9 +101,9 @@ jobs:
- attach_workspace:
at: /tmp/workspace
- restore_cache:
- key: v2-pkg-cache
+ key: v3-pkg-cache
- restore_cache:
- key: v2-tree-{{ .Environment.CIRCLE_SHA1 }}
+ key: v3-tree-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: Run abci-cli tests
command: |
@@ -116,9 +116,9 @@ jobs:
- attach_workspace:
at: /tmp/workspace
- restore_cache:
- key: v2-pkg-cache
+ key: v3-pkg-cache
- restore_cache:
- key: v2-tree-{{ .Environment.CIRCLE_SHA1 }}
+ key: v3-tree-{{ .Environment.CIRCLE_SHA1 }}
- run: sudo apt-get update && sudo apt-get install -y --no-install-recommends bsdmainutils
- run:
name: Run tests
@@ -131,9 +131,9 @@ jobs:
- attach_workspace:
at: /tmp/workspace
- restore_cache:
- key: v2-pkg-cache
+ key: v3-pkg-cache
- restore_cache:
- key: v2-tree-{{ .Environment.CIRCLE_SHA1 }}
+ key: v3-tree-{{ .Environment.CIRCLE_SHA1 }}
- run: mkdir -p /tmp/logs
- run:
name: Run tests
@@ -156,9 +156,9 @@ jobs:
- attach_workspace:
at: /tmp/workspace
- restore_cache:
- key: v2-pkg-cache
+ key: v3-pkg-cache
- restore_cache:
- key: v2-tree-{{ .Environment.CIRCLE_SHA1 }}
+ key: v3-tree-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: Run tests
command: bash test/persist/test_failure_indices.sh
@@ -181,7 +181,7 @@ jobs:
- attach_workspace:
at: /tmp/workspace
- restore_cache:
- key: v2-tree-{{ .Environment.CIRCLE_SHA1 }}
+ key: v3-tree-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: gather
command: |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6fcab4b8..d4551a56 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,37 @@
# Changelog
+BREAKING CHANGES:
+- [crypto] Refactor `tendermint/crypto` into many subpackages
+- [libs/common] remove exponentially distributed random numbers
+
+IMPROVEMENTS:
+- [config] Increase default send/recv rates to 5 mB/s
+
+## 0.22.4
+
+*July 14th, 2018*
+
+BREAKING CHANGES:
+- [genesis] removed deprecated `app_options` field.
+- [types] Genesis.AppStateJSON -> Genesis.AppState
+
+FEATURES:
+- [tools] Merged in from github.com/tendermint/tools
+
+BUG FIXES:
+- [tools/tm-bench] Various fixes
+- [consensus] Wait for WAL to stop on shutdown
+- [abci] Fix #1891, pending requests cannot hang when abci server dies. Previously a crash in BeginBlock could leave tendermint in broken state.
+
+## 0.22.3
+
+*July 10th, 2018*
+
+IMPROVEMENTS
+- Update dependencies
+ * pin all values in Gopkg.toml to version or commit
+ * update golang/protobuf to v1.1.0
+
## 0.22.2
*July 10th, 2018*
@@ -32,8 +64,6 @@ BUG FIXES
already in the validator set.
* [consensus] Shut down WAL properly.
-BUG FIXES:
-- [abci] Fix #1891, pending requests cannot hang when abci server dies. Previously a crash in BeginBlock could leave tendermint in broken state.
## 0.22.0
diff --git a/Gopkg.lock b/Gopkg.lock
index b1beaa20..44192a01 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -11,10 +11,9 @@
branch = "master"
name = "github.com/btcsuite/btcd"
packages = ["btcec"]
- revision = "86fed781132ac890ee03e906e4ecd5d6fa180c64"
+ revision = "fdfc19097e7ac6b57035062056f5b7b4638b8898"
[[projects]]
- branch = "master"
name = "github.com/btcsuite/btcutil"
packages = [
"base58",
@@ -29,16 +28,15 @@
version = "v1.1.0"
[[projects]]
- branch = "master"
name = "github.com/ebuchman/fail-test"
packages = ["."]
revision = "95f809107225be108efcf10a3509e4ea6ceef3c4"
[[projects]]
- branch = "master"
name = "github.com/fortytw2/leaktest"
packages = ["."]
- revision = "b008db64ef8daabb22ff6daa557f33b41d8f6ccd"
+ revision = "a5ef70473c97b71626b9abeda80ee92ba2a7de9e"
+ version = "v1.2.0"
[[projects]]
name = "github.com/fsnotify/fsnotify"
@@ -180,13 +178,12 @@
version = "v1.0.0"
[[projects]]
- branch = "master"
name = "github.com/prometheus/client_golang"
packages = [
"prometheus",
"prometheus/promhttp"
]
- revision = "d6a9817c4afc94d51115e4a30d449056a3fbf547"
+ revision = "ae27198cdd90bf12cd134ad79d1366a6cf49f632"
[[projects]]
branch = "master"
@@ -213,10 +210,9 @@
"nfs",
"xfs"
]
- revision = "40f013a808ec4fa79def444a1a56de4d1727efcb"
+ revision = "ae68e2d4c00fed4943b5f6698d504a5fe083da8a"
[[projects]]
- branch = "master"
name = "github.com/rcrowley/go-metrics"
packages = ["."]
revision = "e2704e165165ec55d062f5919b4b29494e9fa790"
@@ -266,8 +262,8 @@
"assert",
"require"
]
- revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
- version = "v1.2.2"
+ revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
+ version = "v1.2.1"
[[projects]]
branch = "master"
@@ -286,7 +282,7 @@
"leveldb/table",
"leveldb/util"
]
- revision = "e2150783cd35f5b607daca48afd8c57ec54cc995"
+ revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445"
[[projects]]
branch = "master"
@@ -326,7 +322,6 @@
revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602"
[[projects]]
- branch = "master"
name = "golang.org/x/net"
packages = [
"context",
@@ -338,7 +333,7 @@
"netutil",
"trace"
]
- revision = "4cb1c02c05b0e749b0365f61ae859a8e0cfceed9"
+ revision = "292b43bbf7cb8d35ddf40f8d5100ef3837cced3f"
[[projects]]
branch = "master"
@@ -347,7 +342,7 @@
"cpu",
"unix"
]
- revision = "7138fd3d9dc8335c567ca206f4333fb75eb05d56"
+ revision = "1b2967e3c290b7c545b3db0deeda16e9be4f98a2"
[[projects]]
name = "golang.org/x/text"
@@ -414,6 +409,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
- inputs-digest = "6e854634d6c203278ce83bef7725cecbcf90023b0d0e440fb3374acedacbd5ad"
+ inputs-digest = "b0718135d5ade0a75c6b8fe703f70eb9d8064ba871ec31abd9ace3c4ab944100"
solver-name = "gps-cdcl"
solver-version = 1
diff --git a/Gopkg.toml b/Gopkg.toml
index ecce0e41..7bf82798 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -23,16 +23,12 @@
# non-go = false
# go-tests = true
# unused-packages = true
+#
+###########################################################
+# NOTE: All packages should be pinned to specific versions.
+# Packages without releases must pin to a commit.
-[[constraint]]
- name = "github.com/ebuchman/fail-test"
- branch = "master"
-
-[[constraint]]
- name = "github.com/fortytw2/leaktest"
- branch = "master"
-
[[constraint]]
name = "github.com/go-kit/kit"
version = "=0.6.0"
@@ -47,16 +43,12 @@
[[constraint]]
name = "github.com/gorilla/websocket"
- version = "~1.2.0"
+ version = "=1.2.0"
[[constraint]]
name = "github.com/pkg/errors"
version = "=0.8.0"
-[[constraint]]
- name = "github.com/rcrowley/go-metrics"
- branch = "master"
-
[[constraint]]
name = "github.com/spf13/cobra"
version = "=0.0.1"
@@ -67,29 +59,60 @@
[[constraint]]
name = "github.com/stretchr/testify"
- version = "~1.2.1"
+ version = "=1.2.1"
[[constraint]]
name = "github.com/tendermint/go-amino"
- version = "~0.10.1"
+ version = "=0.10.1"
[[constraint]]
name = "google.golang.org/grpc"
- version = "~1.11.3"
+ version = "=1.11.3"
-# this got updated and broke, so locked to an old working commit ...
+[[constraint]]
+ name = "github.com/fortytw2/leaktest"
+ version = "=1.2.0"
+
+###################################
+## Some repos dont have releases.
+## Pin to revision
+
+## We can remove this one by updating protobuf to v1.1.0
+## but then the grpc tests break with
+#--- FAIL: TestBroadcastTx (0.01s)
+#panic: message/group field common.KVPair:bytes without pointer [recovered]
+# panic: message/group field common.KVPair:bytes without pointer
+#
+# ...
+#
+# github.com/tendermint/tendermint/rpc/grpc_test.TestBroadcastTx(0xc420a5ab40)
+# /go/src/github.com/tendermint/tendermint/rpc/grpc/grpc_test.go:29 +0x141
[[override]]
name = "google.golang.org/genproto"
revision = "7fd901a49ba6a7f87732eb344f6e3c5b19d1b200"
+[[constraint]]
+ name = "github.com/ebuchman/fail-test"
+ revision = "95f809107225be108efcf10a3509e4ea6ceef3c4"
+
+# last revision used by go-crypto
+[[constraint]]
+ name = "github.com/btcsuite/btcutil"
+ revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4"
+
+# Haven't made a release since 2016.
+[[constraint]]
+ name = "github.com/prometheus/client_golang"
+ revision = "ae27198cdd90bf12cd134ad79d1366a6cf49f632"
+
+[[constraint]]
+ name = "github.com/rcrowley/go-metrics"
+ revision = "e2704e165165ec55d062f5919b4b29494e9fa790"
+
+[[constraint]]
+ name = "golang.org/x/net"
+ revision = "292b43bbf7cb8d35ddf40f8d5100ef3837cced3f"
+
[prune]
go-tests = true
unused-packages = true
-
-[[constraint]]
- name = "github.com/prometheus/client_golang"
- branch = "master"
-
-[[constraint]]
- branch = "master"
- name = "golang.org/x/net"
diff --git a/Makefile b/Makefile
index b929dbe5..e5a52796 100644
--- a/Makefile
+++ b/Makefile
@@ -114,7 +114,7 @@ protoc_libs:
## See https://stackoverflow.com/a/25518702
protoc $(INCLUDE) --go_out=plugins=grpc:. libs/common/*.proto
@echo "--> adding nolint declarations to protobuf generated files"
- @awk '/package libs/common/ { print "//nolint: gas"; print; next }1' libs/common/types.pb.go > libs/common/types.pb.go.new
+ @awk '/package common/ { print "//nolint: gas"; print; next }1' libs/common/types.pb.go > libs/common/types.pb.go.new
@mv libs/common/types.pb.go.new libs/common/types.pb.go
gen_certs: clean_certs
diff --git a/README.md b/README.md
index 2f7d13cd..6268e054 100644
--- a/README.md
+++ b/README.md
@@ -50,13 +50,13 @@ Go version | Go1.9 or higher
## Install
-See the [install instructions](/docs/install.md)
+See the [install instructions](/docs/introduction/install.md)
## Quick Start
- [Single node](/docs/using-tendermint.md)
- [Local cluster using docker-compose](/networks/local)
-- [Remote cluster using terraform and ansible](/docs/terraform-and-ansible.md)
+- [Remote cluster using terraform and ansible](/docs/networks/terraform-and-ansible.md)
- [Join the public testnet](https://cosmos.network/testnet)
## Resources
diff --git a/benchmarks/codec_test.go b/benchmarks/codec_test.go
index 53cbf632..9e12bbe9 100644
--- a/benchmarks/codec_test.go
+++ b/benchmarks/codec_test.go
@@ -7,7 +7,7 @@ import (
"github.com/tendermint/go-amino"
proto "github.com/tendermint/tendermint/benchmarks/proto"
- "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/p2p"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)
@@ -16,7 +16,7 @@ func BenchmarkEncodeStatusWire(b *testing.B) {
b.StopTimer()
cdc := amino.NewCodec()
ctypes.RegisterAmino(cdc)
- nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
+ nodeKey := p2p.NodeKey{PrivKey: ed25519.GenPrivKeyEd25519()}
status := &ctypes.ResultStatus{
NodeInfo: p2p.NodeInfo{
ID: nodeKey.ID(),
@@ -52,7 +52,7 @@ func BenchmarkEncodeNodeInfoWire(b *testing.B) {
b.StopTimer()
cdc := amino.NewCodec()
ctypes.RegisterAmino(cdc)
- nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
+ nodeKey := p2p.NodeKey{PrivKey: ed25519.GenPrivKeyEd25519()}
nodeInfo := p2p.NodeInfo{
ID: nodeKey.ID(),
Moniker: "SOMENAME",
@@ -77,7 +77,7 @@ func BenchmarkEncodeNodeInfoBinary(b *testing.B) {
b.StopTimer()
cdc := amino.NewCodec()
ctypes.RegisterAmino(cdc)
- nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
+ nodeKey := p2p.NodeKey{PrivKey: ed25519.GenPrivKeyEd25519()}
nodeInfo := p2p.NodeInfo{
ID: nodeKey.ID(),
Moniker: "SOMENAME",
@@ -98,7 +98,7 @@ func BenchmarkEncodeNodeInfoBinary(b *testing.B) {
func BenchmarkEncodeNodeInfoProto(b *testing.B) {
b.StopTimer()
- nodeKey := p2p.NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
+ nodeKey := p2p.NodeKey{PrivKey: ed25519.GenPrivKeyEd25519()}
nodeID := string(nodeKey.ID())
someName := "SOMENAME"
someAddr := "SOMEADDR"
diff --git a/blockchain/pool_test.go b/blockchain/pool_test.go
index c2f615f9..dcb046db 100644
--- a/blockchain/pool_test.go
+++ b/blockchain/pool_test.go
@@ -1,7 +1,6 @@
package blockchain
import (
- "math/rand"
"testing"
"time"
@@ -25,7 +24,7 @@ func makePeers(numPeers int, minHeight, maxHeight int64) map[p2p.ID]testPeer {
peers := make(map[p2p.ID]testPeer, numPeers)
for i := 0; i < numPeers; i++ {
peerID := p2p.ID(cmn.RandStr(12))
- height := minHeight + rand.Int63n(maxHeight-minHeight)
+ height := minHeight + cmn.RandInt63n(maxHeight-minHeight)
peers[peerID] = testPeer{peerID, height}
}
return peers
diff --git a/blockchain/wire.go b/blockchain/wire.go
index 70b50565..ff02d58c 100644
--- a/blockchain/wire.go
+++ b/blockchain/wire.go
@@ -2,12 +2,12 @@ package blockchain
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
RegisterBlockchainMessages(cdc)
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
}
diff --git a/cmd/priv_val_server/main.go b/cmd/priv_val_server/main.go
index 20c23f4c..7b008049 100644
--- a/cmd/priv_val_server/main.go
+++ b/cmd/priv_val_server/main.go
@@ -4,7 +4,7 @@ import (
"flag"
"os"
- crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
@@ -37,7 +37,7 @@ func main() {
*chainID,
*addr,
pv,
- crypto.GenPrivKeyEd25519(),
+ ed25519.GenPrivKeyEd25519(),
)
err := rs.Start()
if err != nil {
diff --git a/cmd/tendermint/commands/wire.go b/cmd/tendermint/commands/wire.go
index a0901913..0f0b536d 100644
--- a/cmd/tendermint/commands/wire.go
+++ b/cmd/tendermint/commands/wire.go
@@ -2,11 +2,11 @@ package commands
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
}
diff --git a/config/config.go b/config/config.go
index 2df8eb8e..eee9798d 100644
--- a/config/config.go
+++ b/config/config.go
@@ -349,9 +349,9 @@ func DefaultP2PConfig() *P2PConfig {
AddrBookStrict: true,
MaxNumPeers: 50,
FlushThrottleTimeout: 100,
- MaxPacketMsgPayloadSize: 1024, // 1 kB
- SendRate: 512000, // 500 kB/s
- RecvRate: 512000, // 500 kB/s
+ MaxPacketMsgPayloadSize: 1024, // 1 kB
+ SendRate: 5120000, // 5 mB/s
+ RecvRate: 5120000, // 5 mB/s
PexReactor: true,
SeedMode: false,
AllowDuplicateIP: true, // so non-breaking yet
diff --git a/consensus/reactor.go b/consensus/reactor.go
index 48ebcad2..3eb1d73a 100644
--- a/consensus/reactor.go
+++ b/consensus/reactor.go
@@ -80,6 +80,9 @@ func (conR *ConsensusReactor) OnStop() {
conR.BaseReactor.OnStop()
conR.unsubscribeFromBroadcastEvents()
conR.conS.Stop()
+ if !conR.FastSync() {
+ conR.conS.Wait()
+ }
}
// SwitchToConsensus switches from fast_sync mode to consensus mode.
diff --git a/consensus/replay.go b/consensus/replay.go
index 3035f75d..dd940998 100644
--- a/consensus/replay.go
+++ b/consensus/replay.go
@@ -273,7 +273,7 @@ func (h *Handshaker) ReplayBlocks(state sm.State, appHash []byte, appBlockHeight
ChainId: h.genDoc.ChainID,
ConsensusParams: csParams,
Validators: validators,
- AppStateBytes: h.genDoc.AppStateJSON,
+ AppStateBytes: h.genDoc.AppState,
}
res, err := proxyApp.Consensus().InitChainSync(req)
if err != nil {
diff --git a/consensus/types/round_state_test.go b/consensus/types/round_state_test.go
index 080178f2..73f4a34d 100644
--- a/consensus/types/round_state_test.go
+++ b/consensus/types/round_state_test.go
@@ -5,9 +5,9 @@ import (
"time"
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
- "github.com/tendermint/tendermint/types"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
+ "github.com/tendermint/tendermint/types"
)
func BenchmarkRoundStateDeepCopy(b *testing.B) {
@@ -23,7 +23,7 @@ func BenchmarkRoundStateDeepCopy(b *testing.B) {
Hash: cmn.RandBytes(20),
},
}
- sig := crypto.SignatureEd25519{}
+ sig := ed25519.SignatureEd25519{}
for i := 0; i < nval; i++ {
precommits[i] = &types.Vote{
ValidatorAddress: types.Address(cmn.RandBytes(20)),
diff --git a/consensus/types/wire.go b/consensus/types/wire.go
index 6342d7eb..9221de96 100644
--- a/consensus/types/wire.go
+++ b/consensus/types/wire.go
@@ -2,11 +2,11 @@ package types
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
}
diff --git a/consensus/wire.go b/consensus/wire.go
index 5f231c0c..cc172bea 100644
--- a/consensus/wire.go
+++ b/consensus/wire.go
@@ -2,7 +2,7 @@ package consensus
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
@@ -10,5 +10,5 @@ var cdc = amino.NewCodec()
func init() {
RegisterConsensusMessages(cdc)
RegisterWALMessages(cdc)
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
}
diff --git a/crypto/README.md b/crypto/README.md
index 32afde69..5fac6733 100644
--- a/crypto/README.md
+++ b/crypto/README.md
@@ -3,8 +3,15 @@
crypto is the cryptographic package adapted for Tendermint's uses
## Importing it
+To get the interfaces,
`import "github.com/tendermint/tendermint/crypto"`
+For any specific algorithm, use its specific module e.g.
+`import "github.com/tendermint/tendermint/crypto/ed25519"`
+
+If you want to decode bytes into one of the types, but don't care about the specific algorithm, use
+`import "github.com/tendermint/tendermint/crypto/amino"`
+
## Binary encoding
For Binary encoding, please refer to the [Tendermint encoding spec](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md).
@@ -16,9 +23,9 @@ crypto `.Bytes()` uses Amino:binary encoding, but Amino:JSON is also supported.
```go
Example Amino:JSON encodings:
-crypto.PrivKeyEd25519 - {"type":"954568A3288910","value":"EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ=="}
+ed25519.PrivKeyEd25519 - {"type":"954568A3288910","value":"EVkqJO/jIXp3rkASXfh9YnyToYXRXhBr6g9cQVxPFnQBP/5povV4HTjvsy530kybxKHwEi85iU8YL0qQhSYVoQ=="}
crypto.SignatureEd25519 - {"type":"6BF5903DA1DB28","value":"77sQNZOrf7ltExpf7AV1WaYPCHbyRLgjBsoWVzcduuLk+jIGmYk+s5R6Emm29p12HeiNAuhUJgdFGmwkpeGJCA=="}
-crypto.PubKeyEd25519 - {"type":"AC26791624DE60","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="}
+ed25519.PubKeyEd25519 - {"type":"AC26791624DE60","value":"AT/+aaL1eB0477Mud9JMm8Sh8BIvOYlPGC9KkIUmFaE="}
crypto.PrivKeySecp256k1 - {"type":"019E82E1B0F798","value":"zx4Pnh67N+g2V+5vZbQzEyRerX9c4ccNZOVzM9RvJ0Y="}
crypto.SignatureSecp256k1 - {"type":"6D1EA416E1FEE8","value":"MEUCIQCIg5TqS1l7I+MKTrSPIuUN2+4m5tA29dcauqn3NhEJ2wIgICaZ+lgRc5aOTVahU/XoLopXKn8BZcl0bnuYWLvohR8="}
crypto.PubKeySecp256k1 - {"type":"F8CCEAEB5AE980","value":"A8lPKJXcNl5VHt1FK8a244K9EJuS4WX1hFBnwisi0IJx"}
diff --git a/crypto/amino.go b/crypto/amino.go
deleted file mode 100644
index 6a8703fc..00000000
--- a/crypto/amino.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package crypto
-
-import (
- amino "github.com/tendermint/go-amino"
-)
-
-var cdc = amino.NewCodec()
-
-func init() {
- // NOTE: It's important that there be no conflicts here,
- // as that would change the canonical representations,
- // and therefore change the address.
- // TODO: Add feature to go-amino to ensure that there
- // are no conflicts.
- RegisterAmino(cdc)
-}
-
-// RegisterAmino registers all crypto related types in the given (amino) codec.
-func RegisterAmino(cdc *amino.Codec) {
- cdc.RegisterInterface((*PubKey)(nil), nil)
- cdc.RegisterConcrete(PubKeyEd25519{},
- "tendermint/PubKeyEd25519", nil)
- cdc.RegisterConcrete(PubKeySecp256k1{},
- "tendermint/PubKeySecp256k1", nil)
-
- cdc.RegisterInterface((*PrivKey)(nil), nil)
- cdc.RegisterConcrete(PrivKeyEd25519{},
- "tendermint/PrivKeyEd25519", nil)
- cdc.RegisterConcrete(PrivKeySecp256k1{},
- "tendermint/PrivKeySecp256k1", nil)
-
- cdc.RegisterInterface((*Signature)(nil), nil)
- cdc.RegisterConcrete(SignatureEd25519{},
- "tendermint/SignatureEd25519", nil)
- cdc.RegisterConcrete(SignatureSecp256k1{},
- "tendermint/SignatureSecp256k1", nil)
-}
diff --git a/crypto/armor.go b/crypto/armor/armor.go
similarity index 100%
rename from crypto/armor.go
rename to crypto/armor/armor.go
diff --git a/crypto/armor_test.go b/crypto/armor/armor_test.go
similarity index 100%
rename from crypto/armor_test.go
rename to crypto/armor/armor_test.go
diff --git a/crypto/crypto.go b/crypto/crypto.go
new file mode 100644
index 00000000..4c097b35
--- /dev/null
+++ b/crypto/crypto.go
@@ -0,0 +1,36 @@
+package crypto
+
+import (
+ cmn "github.com/tendermint/tendermint/libs/common"
+)
+
+type PrivKey interface {
+ Bytes() []byte
+ Sign(msg []byte) (Signature, error)
+ PubKey() PubKey
+ Equals(PrivKey) bool
+}
+
+// An address is a []byte, but hex-encoded even in JSON.
+// []byte leaves us the option to change the address length.
+// Use an alias so Unmarshal methods (with ptr receivers) are available too.
+type Address = cmn.HexBytes
+
+type PubKey interface {
+ Address() Address
+ Bytes() []byte
+ VerifyBytes(msg []byte, sig Signature) bool
+ Equals(PubKey) bool
+}
+
+type Signature interface {
+ Bytes() []byte
+ IsZero() bool
+ Equals(Signature) bool
+}
+
+type Symmetric interface {
+ Keygen() []byte
+ Encrypt(plaintext []byte, secret []byte) (ciphertext []byte)
+ Decrypt(ciphertext []byte, secret []byte) (plaintext []byte, err error)
+}
diff --git a/crypto/doc.go b/crypto/doc.go
index 544e0df3..112cd21e 100644
--- a/crypto/doc.go
+++ b/crypto/doc.go
@@ -22,7 +22,7 @@
// pubKey := key.PubKey()
// For example:
-// privKey, err := crypto.GenPrivKeyEd25519()
+// privKey, err := ed25519.GenPrivKeyEd25519()
// if err != nil {
// ...
// }
diff --git a/crypto/ed25519/ed25519.go b/crypto/ed25519/ed25519.go
new file mode 100644
index 00000000..899172e8
--- /dev/null
+++ b/crypto/ed25519/ed25519.go
@@ -0,0 +1,205 @@
+package ed25519
+
+import (
+ "bytes"
+ "crypto/subtle"
+ "fmt"
+
+ "github.com/tendermint/ed25519"
+ "github.com/tendermint/ed25519/extra25519"
+ amino "github.com/tendermint/go-amino"
+ "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/tmhash"
+ cmn "github.com/tendermint/tendermint/libs/common"
+)
+
+//-------------------------------------
+
+var _ crypto.PrivKey = PrivKeyEd25519{}
+
+const (
+ Ed25519PrivKeyAminoRoute = "tendermint/PrivKeyEd25519"
+ Ed25519PubKeyAminoRoute = "tendermint/PubKeyEd25519"
+ Ed25519SignatureAminoRoute = "tendermint/SignatureEd25519"
+)
+
+var cdc = amino.NewCodec()
+
+func init() {
+ // NOTE: It's important that there be no conflicts here,
+ // as that would change the canonical representations,
+ // and therefore change the address.
+ // TODO: Add feature to go-amino to ensure that there
+ // are no conflicts.
+ cdc.RegisterInterface((*crypto.PubKey)(nil), nil)
+ cdc.RegisterConcrete(PubKeyEd25519{},
+ Ed25519PubKeyAminoRoute, nil)
+
+ cdc.RegisterInterface((*crypto.PrivKey)(nil), nil)
+ cdc.RegisterConcrete(PrivKeyEd25519{},
+ Ed25519PrivKeyAminoRoute, nil)
+
+ cdc.RegisterInterface((*crypto.Signature)(nil), nil)
+ cdc.RegisterConcrete(SignatureEd25519{},
+ Ed25519SignatureAminoRoute, nil)
+}
+
+// Implements crypto.PrivKey
+type PrivKeyEd25519 [64]byte
+
+func (privKey PrivKeyEd25519) Bytes() []byte {
+ return cdc.MustMarshalBinaryBare(privKey)
+}
+
+func (privKey PrivKeyEd25519) Sign(msg []byte) (crypto.Signature, error) {
+ privKeyBytes := [64]byte(privKey)
+ signatureBytes := ed25519.Sign(&privKeyBytes, msg)
+ return SignatureEd25519(*signatureBytes), nil
+}
+
+func (privKey PrivKeyEd25519) PubKey() crypto.PubKey {
+ privKeyBytes := [64]byte(privKey)
+ pubBytes := *ed25519.MakePublicKey(&privKeyBytes)
+ return PubKeyEd25519(pubBytes)
+}
+
+// Equals - you probably don't need to use this.
+// Runs in constant time based on length of the keys.
+func (privKey PrivKeyEd25519) Equals(other crypto.PrivKey) bool {
+ if otherEd, ok := other.(PrivKeyEd25519); ok {
+ return subtle.ConstantTimeCompare(privKey[:], otherEd[:]) == 1
+ } else {
+ return false
+ }
+}
+
+func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte {
+ keyCurve25519 := new([32]byte)
+ privKeyBytes := [64]byte(privKey)
+ extra25519.PrivateKeyToCurve25519(keyCurve25519, &privKeyBytes)
+ return keyCurve25519
+}
+
+// Deterministically generates new priv-key bytes from key.
+func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 {
+ bz, err := cdc.MarshalBinaryBare(struct {
+ PrivKey [64]byte
+ Index int
+ }{privKey, index})
+ if err != nil {
+ panic(err)
+ }
+ newBytes := crypto.Sha256(bz)
+ newKey := new([64]byte)
+ copy(newKey[:32], newBytes)
+ ed25519.MakePublicKey(newKey)
+ return PrivKeyEd25519(*newKey)
+}
+
+func GenPrivKeyEd25519() PrivKeyEd25519 {
+ privKeyBytes := new([64]byte)
+ copy(privKeyBytes[:32], crypto.CRandBytes(32))
+ ed25519.MakePublicKey(privKeyBytes)
+ return PrivKeyEd25519(*privKeyBytes)
+}
+
+// NOTE: secret should be the output of a KDF like bcrypt,
+// if it's derived from user input.
+func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 {
+ privKey32 := crypto.Sha256(secret) // Not Ripemd160 because we want 32 bytes.
+ privKeyBytes := new([64]byte)
+ copy(privKeyBytes[:32], privKey32)
+ ed25519.MakePublicKey(privKeyBytes)
+ return PrivKeyEd25519(*privKeyBytes)
+}
+
+//-------------------------------------
+
+var _ crypto.PubKey = PubKeyEd25519{}
+
+const PubKeyEd25519Size = 32
+
+// Implements PubKeyInner
+type PubKeyEd25519 [PubKeyEd25519Size]byte
+
+// Address is the SHA256-20 of the raw pubkey bytes.
+func (pubKey PubKeyEd25519) Address() crypto.Address {
+ return crypto.Address(tmhash.Sum(pubKey[:]))
+}
+
+func (pubKey PubKeyEd25519) Bytes() []byte {
+ bz, err := cdc.MarshalBinaryBare(pubKey)
+ if err != nil {
+ panic(err)
+ }
+ return bz
+}
+
+func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ crypto.Signature) bool {
+ // make sure we use the same algorithm to sign
+ sig, ok := sig_.(SignatureEd25519)
+ if !ok {
+ return false
+ }
+ pubKeyBytes := [PubKeyEd25519Size]byte(pubKey)
+ sigBytes := [SignatureEd25519Size]byte(sig)
+ return ed25519.Verify(&pubKeyBytes, msg, &sigBytes)
+}
+
+// For use with golang/crypto/nacl/box
+// If error, returns nil.
+func (pubKey PubKeyEd25519) ToCurve25519() *[PubKeyEd25519Size]byte {
+ keyCurve25519, pubKeyBytes := new([PubKeyEd25519Size]byte), [PubKeyEd25519Size]byte(pubKey)
+ ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes)
+ if !ok {
+ return nil
+ }
+ return keyCurve25519
+}
+
+func (pubKey PubKeyEd25519) String() string {
+ return fmt.Sprintf("PubKeyEd25519{%X}", pubKey[:])
+}
+
+func (pubKey PubKeyEd25519) Equals(other crypto.PubKey) bool {
+ if otherEd, ok := other.(PubKeyEd25519); ok {
+ return bytes.Equal(pubKey[:], otherEd[:])
+ } else {
+ return false
+ }
+}
+
+//-------------------------------------
+
+var _ crypto.Signature = SignatureEd25519{}
+
+const SignatureEd25519Size = 64
+
+// Implements crypto.Signature
+type SignatureEd25519 [SignatureEd25519Size]byte
+
+func (sig SignatureEd25519) Bytes() []byte {
+ bz, err := cdc.MarshalBinaryBare(sig)
+ if err != nil {
+ panic(err)
+ }
+ return bz
+}
+
+func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 }
+
+func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", cmn.Fingerprint(sig[:])) }
+
+func (sig SignatureEd25519) Equals(other crypto.Signature) bool {
+ if otherEd, ok := other.(SignatureEd25519); ok {
+ return subtle.ConstantTimeCompare(sig[:], otherEd[:]) == 1
+ } else {
+ return false
+ }
+}
+
+func SignatureEd25519FromBytes(data []byte) crypto.Signature {
+ var sig SignatureEd25519
+ copy(sig[:], data)
+ return sig
+}
diff --git a/crypto/ed25519/ed25519_test.go b/crypto/ed25519/ed25519_test.go
new file mode 100644
index 00000000..6ec88cb3
--- /dev/null
+++ b/crypto/ed25519/ed25519_test.go
@@ -0,0 +1,40 @@
+package ed25519_test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
+)
+
+func TestGeneratePrivKey(t *testing.T) {
+ testPriv := ed25519.GenPrivKeyEd25519()
+ testGenerate := testPriv.Generate(1)
+ signBytes := []byte("something to sign")
+ pub := testGenerate.PubKey()
+ sig, err := testGenerate.Sign(signBytes)
+ assert.NoError(t, err)
+ assert.True(t, pub.VerifyBytes(signBytes, sig))
+}
+
+func TestSignAndValidateEd25519(t *testing.T) {
+
+ privKey := ed25519.GenPrivKeyEd25519()
+ pubKey := privKey.PubKey()
+
+ msg := crypto.CRandBytes(128)
+ sig, err := privKey.Sign(msg)
+ require.Nil(t, err)
+
+ // Test the signature
+ assert.True(t, pubKey.VerifyBytes(msg, sig))
+
+ // Mutate the signature, just one bit.
+ sigEd := sig.(ed25519.SignatureEd25519)
+ sigEd[7] ^= byte(0x01)
+ sig = sigEd
+
+ assert.False(t, pubKey.VerifyBytes(msg, sig))
+}
diff --git a/crypto/encoding/amino/amino.go b/crypto/encoding/amino/amino.go
new file mode 100644
index 00000000..f87d8988
--- /dev/null
+++ b/crypto/encoding/amino/amino.go
@@ -0,0 +1,56 @@
+package crypto
+
+import (
+ amino "github.com/tendermint/go-amino"
+ "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
+ "github.com/tendermint/tendermint/crypto/secp256k1"
+)
+
+var cdc = amino.NewCodec()
+
+func init() {
+ // NOTE: It's important that there be no conflicts here,
+ // as that would change the canonical representations,
+ // and therefore change the address.
+ // TODO: Add feature to go-amino to ensure that there
+ // are no conflicts.
+ RegisterAmino(cdc)
+}
+
+// RegisterAmino registers all crypto related types in the given (amino) codec.
+func RegisterAmino(cdc *amino.Codec) {
+ // These are all written here instead of
+ cdc.RegisterInterface((*crypto.PubKey)(nil), nil)
+ cdc.RegisterConcrete(ed25519.PubKeyEd25519{},
+ "tendermint/PubKeyEd25519", nil)
+ cdc.RegisterConcrete(secp256k1.PubKeySecp256k1{},
+ "tendermint/PubKeySecp256k1", nil)
+
+ cdc.RegisterInterface((*crypto.PrivKey)(nil), nil)
+ cdc.RegisterConcrete(ed25519.PrivKeyEd25519{},
+ "tendermint/PrivKeyEd25519", nil)
+ cdc.RegisterConcrete(secp256k1.PrivKeySecp256k1{},
+ "tendermint/PrivKeySecp256k1", nil)
+
+ cdc.RegisterInterface((*crypto.Signature)(nil), nil)
+ cdc.RegisterConcrete(ed25519.SignatureEd25519{},
+ "tendermint/SignatureEd25519", nil)
+ cdc.RegisterConcrete(secp256k1.SignatureSecp256k1{},
+ "tendermint/SignatureSecp256k1", nil)
+}
+
+func PrivKeyFromBytes(privKeyBytes []byte) (privKey crypto.PrivKey, err error) {
+ err = cdc.UnmarshalBinaryBare(privKeyBytes, &privKey)
+ return
+}
+
+func PubKeyFromBytes(pubKeyBytes []byte) (pubKey crypto.PubKey, err error) {
+ err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey)
+ return
+}
+
+func SignatureFromBytes(pubKeyBytes []byte) (pubKey crypto.Signature, err error) {
+ err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey)
+ return
+}
diff --git a/crypto/encode_test.go b/crypto/encoding/amino/encode_test.go
similarity index 72%
rename from crypto/encode_test.go
rename to crypto/encoding/amino/encode_test.go
index 16555bf7..450e7d63 100644
--- a/crypto/encode_test.go
+++ b/crypto/encoding/amino/encode_test.go
@@ -6,6 +6,9 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
+ "github.com/tendermint/tendermint/crypto/secp256k1"
)
type byter interface {
@@ -56,64 +59,70 @@ func ExamplePrintRegisteredTypes() {
func TestKeyEncodings(t *testing.T) {
cases := []struct {
- privKey PrivKey
+ privKey crypto.PrivKey
privSize, pubSize int // binary sizes
}{
{
- privKey: GenPrivKeyEd25519(),
+ privKey: ed25519.GenPrivKeyEd25519(),
privSize: 69,
pubSize: 37,
},
{
- privKey: GenPrivKeySecp256k1(),
+ privKey: secp256k1.GenPrivKeySecp256k1(),
privSize: 37,
pubSize: 38,
},
}
- for _, tc := range cases {
+ for tcIndex, tc := range cases {
// Check (de/en)codings of PrivKeys.
- var priv2, priv3 PrivKey
+ var priv2, priv3 crypto.PrivKey
checkAminoBinary(t, tc.privKey, &priv2, tc.privSize)
- assert.EqualValues(t, tc.privKey, priv2)
+ assert.EqualValues(t, tc.privKey, priv2, "tc #%d", tcIndex)
checkAminoJSON(t, tc.privKey, &priv3, false) // TODO also check Prefix bytes.
- assert.EqualValues(t, tc.privKey, priv3)
+ assert.EqualValues(t, tc.privKey, priv3, "tc #%d", tcIndex)
// Check (de/en)codings of Signatures.
- var sig1, sig2, sig3 Signature
+ var sig1, sig2, sig3 crypto.Signature
sig1, err := tc.privKey.Sign([]byte("something"))
- assert.NoError(t, err)
+ assert.NoError(t, err, "tc #%d", tcIndex)
checkAminoBinary(t, sig1, &sig2, -1) // Signature size changes for Secp anyways.
- assert.EqualValues(t, sig1, sig2)
+ assert.EqualValues(t, sig1, sig2, "tc #%d", tcIndex)
checkAminoJSON(t, sig1, &sig3, false) // TODO also check Prefix bytes.
- assert.EqualValues(t, sig1, sig3)
+ assert.EqualValues(t, sig1, sig3, "tc #%d", tcIndex)
// Check (de/en)codings of PubKeys.
pubKey := tc.privKey.PubKey()
- var pub2, pub3 PubKey
+ var pub2, pub3 crypto.PubKey
checkAminoBinary(t, pubKey, &pub2, tc.pubSize)
- assert.EqualValues(t, pubKey, pub2)
+ assert.EqualValues(t, pubKey, pub2, "tc #%d", tcIndex)
checkAminoJSON(t, pubKey, &pub3, false) // TODO also check Prefix bytes.
- assert.EqualValues(t, pubKey, pub3)
+ assert.EqualValues(t, pubKey, pub3, "tc #%d", tcIndex)
}
}
func TestNilEncodings(t *testing.T) {
// Check nil Signature.
- var a, b Signature
+ var a, b crypto.Signature
checkAminoJSON(t, &a, &b, true)
assert.EqualValues(t, a, b)
// Check nil PubKey.
- var c, d PubKey
+ var c, d crypto.PubKey
checkAminoJSON(t, &c, &d, true)
assert.EqualValues(t, c, d)
// Check nil PrivKey.
- var e, f PrivKey
+ var e, f crypto.PrivKey
checkAminoJSON(t, &e, &f, true)
assert.EqualValues(t, e, f)
}
+
+func TestPubKeyInvalidDataProperReturnsEmpty(t *testing.T) {
+ pk, err := PubKeyFromBytes([]byte("foo"))
+ require.NotNil(t, err, "expecting a non-nil error")
+ require.Nil(t, pk, "expecting an empty public key on error")
+}
diff --git a/crypto/hash.go b/crypto/hash.go
index 165b1e15..c1fb41f7 100644
--- a/crypto/hash.go
+++ b/crypto/hash.go
@@ -2,6 +2,7 @@ package crypto
import (
"crypto/sha256"
+
"golang.org/x/crypto/ripemd160"
)
diff --git a/crypto/hkdfchacha20poly1305/hkdfchachapoly.go b/crypto/hkdfchacha20poly1305/hkdfchachapoly.go
index ab3b9df3..4bf24cb1 100644
--- a/crypto/hkdfchacha20poly1305/hkdfchachapoly.go
+++ b/crypto/hkdfchacha20poly1305/hkdfchachapoly.go
@@ -14,6 +14,7 @@ import (
"golang.org/x/crypto/hkdf"
)
+// Implements crypto.AEAD
type hkdfchacha20poly1305 struct {
key [KeySize]byte
}
diff --git a/crypto/priv_key.go b/crypto/priv_key.go
deleted file mode 100644
index dbfe64c3..00000000
--- a/crypto/priv_key.go
+++ /dev/null
@@ -1,164 +0,0 @@
-package crypto
-
-import (
- "crypto/subtle"
-
- secp256k1 "github.com/btcsuite/btcd/btcec"
- "github.com/tendermint/ed25519"
- "github.com/tendermint/ed25519/extra25519"
-)
-
-func PrivKeyFromBytes(privKeyBytes []byte) (privKey PrivKey, err error) {
- err = cdc.UnmarshalBinaryBare(privKeyBytes, &privKey)
- return
-}
-
-//----------------------------------------
-
-type PrivKey interface {
- Bytes() []byte
- Sign(msg []byte) (Signature, error)
- PubKey() PubKey
- Equals(PrivKey) bool
-}
-
-//-------------------------------------
-
-var _ PrivKey = PrivKeyEd25519{}
-
-// Implements PrivKey
-type PrivKeyEd25519 [64]byte
-
-func (privKey PrivKeyEd25519) Bytes() []byte {
- return cdc.MustMarshalBinaryBare(privKey)
-}
-
-func (privKey PrivKeyEd25519) Sign(msg []byte) (Signature, error) {
- privKeyBytes := [64]byte(privKey)
- signatureBytes := ed25519.Sign(&privKeyBytes, msg)
- return SignatureEd25519(*signatureBytes), nil
-}
-
-func (privKey PrivKeyEd25519) PubKey() PubKey {
- privKeyBytes := [64]byte(privKey)
- pubBytes := *ed25519.MakePublicKey(&privKeyBytes)
- return PubKeyEd25519(pubBytes)
-}
-
-// Equals - you probably don't need to use this.
-// Runs in constant time based on length of the keys.
-func (privKey PrivKeyEd25519) Equals(other PrivKey) bool {
- if otherEd, ok := other.(PrivKeyEd25519); ok {
- return subtle.ConstantTimeCompare(privKey[:], otherEd[:]) == 1
- } else {
- return false
- }
-}
-
-func (privKey PrivKeyEd25519) ToCurve25519() *[32]byte {
- keyCurve25519 := new([32]byte)
- privKeyBytes := [64]byte(privKey)
- extra25519.PrivateKeyToCurve25519(keyCurve25519, &privKeyBytes)
- return keyCurve25519
-}
-
-// Deterministically generates new priv-key bytes from key.
-func (privKey PrivKeyEd25519) Generate(index int) PrivKeyEd25519 {
- bz, err := cdc.MarshalBinaryBare(struct {
- PrivKey [64]byte
- Index int
- }{privKey, index})
- if err != nil {
- panic(err)
- }
- newBytes := Sha256(bz)
- newKey := new([64]byte)
- copy(newKey[:32], newBytes)
- ed25519.MakePublicKey(newKey)
- return PrivKeyEd25519(*newKey)
-}
-
-func GenPrivKeyEd25519() PrivKeyEd25519 {
- privKeyBytes := new([64]byte)
- copy(privKeyBytes[:32], CRandBytes(32))
- ed25519.MakePublicKey(privKeyBytes)
- return PrivKeyEd25519(*privKeyBytes)
-}
-
-// NOTE: secret should be the output of a KDF like bcrypt,
-// if it's derived from user input.
-func GenPrivKeyEd25519FromSecret(secret []byte) PrivKeyEd25519 {
- privKey32 := Sha256(secret) // Not Ripemd160 because we want 32 bytes.
- privKeyBytes := new([64]byte)
- copy(privKeyBytes[:32], privKey32)
- ed25519.MakePublicKey(privKeyBytes)
- return PrivKeyEd25519(*privKeyBytes)
-}
-
-//-------------------------------------
-
-var _ PrivKey = PrivKeySecp256k1{}
-
-// Implements PrivKey
-type PrivKeySecp256k1 [32]byte
-
-func (privKey PrivKeySecp256k1) Bytes() []byte {
- return cdc.MustMarshalBinaryBare(privKey)
-}
-
-func (privKey PrivKeySecp256k1) Sign(msg []byte) (Signature, error) {
- priv__, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:])
- sig__, err := priv__.Sign(Sha256(msg))
- if err != nil {
- return nil, err
- }
- return SignatureSecp256k1(sig__.Serialize()), nil
-}
-
-func (privKey PrivKeySecp256k1) PubKey() PubKey {
- _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:])
- var pub PubKeySecp256k1
- copy(pub[:], pub__.SerializeCompressed())
- return pub
-}
-
-// Equals - you probably don't need to use this.
-// Runs in constant time based on length of the keys.
-func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool {
- if otherSecp, ok := other.(PrivKeySecp256k1); ok {
- return subtle.ConstantTimeCompare(privKey[:], otherSecp[:]) == 1
- } else {
- return false
- }
-}
-
-/*
-// Deterministically generates new priv-key bytes from key.
-func (key PrivKeySecp256k1) Generate(index int) PrivKeySecp256k1 {
- newBytes := cdc.BinarySha256(struct {
- PrivKey [64]byte
- Index int
- }{key, index})
- var newKey [64]byte
- copy(newKey[:], newBytes)
- return PrivKeySecp256k1(newKey)
-}
-*/
-
-func GenPrivKeySecp256k1() PrivKeySecp256k1 {
- privKeyBytes := [32]byte{}
- copy(privKeyBytes[:], CRandBytes(32))
- priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKeyBytes[:])
- copy(privKeyBytes[:], priv.Serialize())
- return PrivKeySecp256k1(privKeyBytes)
-}
-
-// NOTE: secret should be the output of a KDF like bcrypt,
-// if it's derived from user input.
-func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1 {
- privKey32 := Sha256(secret) // Not Ripemd160 because we want 32 bytes.
- priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey32)
- privKeyBytes := [32]byte{}
- copy(privKeyBytes[:], priv.Serialize())
- return PrivKeySecp256k1(privKeyBytes)
-}
diff --git a/crypto/priv_key_test.go b/crypto/priv_key_test.go
deleted file mode 100644
index c1ae33ed..00000000
--- a/crypto/priv_key_test.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package crypto_test
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/tendermint/tendermint/crypto"
-)
-
-func TestGeneratePrivKey(t *testing.T) {
- testPriv := crypto.GenPrivKeyEd25519()
- testGenerate := testPriv.Generate(1)
- signBytes := []byte("something to sign")
- pub := testGenerate.PubKey()
- sig, err := testGenerate.Sign(signBytes)
- assert.NoError(t, err)
- assert.True(t, pub.VerifyBytes(signBytes, sig))
-}
-
-/*
-
-type BadKey struct {
- PrivKeyEd25519
-}
-
-func TestReadPrivKey(t *testing.T) {
- assert, require := assert.New(t), require.New(t)
-
- // garbage in, garbage out
- garbage := []byte("hjgewugfbiewgofwgewr")
- XXX This test wants to register BadKey globally to crypto,
- but we don't want to support that.
- _, err := PrivKeyFromBytes(garbage)
- require.Error(err)
-
- edKey := GenPrivKeyEd25519()
- badKey := BadKey{edKey}
-
- cases := []struct {
- key PrivKey
- valid bool
- }{
- {edKey, true},
- {badKey, false},
- }
-
- for i, tc := range cases {
- data := tc.key.Bytes()
- fmt.Println(">>>", data)
- key, err := PrivKeyFromBytes(data)
- fmt.Printf("!!! %#v\n", key, err)
- if tc.valid {
- assert.NoError(err, "%d", i)
- assert.Equal(tc.key, key, "%d", i)
- } else {
- assert.Error(err, "%d: %#v", i, key)
- }
- }
-}
-*/
diff --git a/crypto/pub_key.go b/crypto/pub_key.go
deleted file mode 100644
index 588c5411..00000000
--- a/crypto/pub_key.go
+++ /dev/null
@@ -1,153 +0,0 @@
-package crypto
-
-import (
- "bytes"
- "crypto/sha256"
- "fmt"
-
- "golang.org/x/crypto/ripemd160"
-
- secp256k1 "github.com/btcsuite/btcd/btcec"
-
- "github.com/tendermint/ed25519"
- "github.com/tendermint/ed25519/extra25519"
-
- cmn "github.com/tendermint/tendermint/libs/common"
-
- "github.com/tendermint/tendermint/crypto/tmhash"
-)
-
-// An address is a []byte, but hex-encoded even in JSON.
-// []byte leaves us the option to change the address length.
-// Use an alias so Unmarshal methods (with ptr receivers) are available too.
-type Address = cmn.HexBytes
-
-func PubKeyFromBytes(pubKeyBytes []byte) (pubKey PubKey, err error) {
- err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey)
- return
-}
-
-//----------------------------------------
-
-type PubKey interface {
- Address() Address
- Bytes() []byte
- VerifyBytes(msg []byte, sig Signature) bool
- Equals(PubKey) bool
-}
-
-//-------------------------------------
-
-var _ PubKey = PubKeyEd25519{}
-
-const PubKeyEd25519Size = 32
-
-// Implements PubKeyInner
-type PubKeyEd25519 [PubKeyEd25519Size]byte
-
-// Address is the SHA256-20 of the raw pubkey bytes.
-func (pubKey PubKeyEd25519) Address() Address {
- return Address(tmhash.Sum(pubKey[:]))
-}
-
-func (pubKey PubKeyEd25519) Bytes() []byte {
- bz, err := cdc.MarshalBinaryBare(pubKey)
- if err != nil {
- panic(err)
- }
- return bz
-}
-
-func (pubKey PubKeyEd25519) VerifyBytes(msg []byte, sig_ Signature) bool {
- // make sure we use the same algorithm to sign
- sig, ok := sig_.(SignatureEd25519)
- if !ok {
- return false
- }
- pubKeyBytes := [PubKeyEd25519Size]byte(pubKey)
- sigBytes := [SignatureEd25519Size]byte(sig)
- return ed25519.Verify(&pubKeyBytes, msg, &sigBytes)
-}
-
-// For use with golang/crypto/nacl/box
-// If error, returns nil.
-func (pubKey PubKeyEd25519) ToCurve25519() *[PubKeyEd25519Size]byte {
- keyCurve25519, pubKeyBytes := new([PubKeyEd25519Size]byte), [PubKeyEd25519Size]byte(pubKey)
- ok := extra25519.PublicKeyToCurve25519(keyCurve25519, &pubKeyBytes)
- if !ok {
- return nil
- }
- return keyCurve25519
-}
-
-func (pubKey PubKeyEd25519) String() string {
- return fmt.Sprintf("PubKeyEd25519{%X}", pubKey[:])
-}
-
-func (pubKey PubKeyEd25519) Equals(other PubKey) bool {
- if otherEd, ok := other.(PubKeyEd25519); ok {
- return bytes.Equal(pubKey[:], otherEd[:])
- } else {
- return false
- }
-}
-
-//-------------------------------------
-
-var _ PubKey = PubKeySecp256k1{}
-
-const PubKeySecp256k1Size = 33
-
-// Implements PubKey.
-// Compressed pubkey (just the x-cord),
-// prefixed with 0x02 or 0x03, depending on the y-cord.
-type PubKeySecp256k1 [PubKeySecp256k1Size]byte
-
-// Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey))
-func (pubKey PubKeySecp256k1) Address() Address {
- hasherSHA256 := sha256.New()
- hasherSHA256.Write(pubKey[:]) // does not error
- sha := hasherSHA256.Sum(nil)
-
- hasherRIPEMD160 := ripemd160.New()
- hasherRIPEMD160.Write(sha) // does not error
- return Address(hasherRIPEMD160.Sum(nil))
-}
-
-func (pubKey PubKeySecp256k1) Bytes() []byte {
- bz, err := cdc.MarshalBinaryBare(pubKey)
- if err != nil {
- panic(err)
- }
- return bz
-}
-
-func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool {
- // and assert same algorithm to sign and verify
- sig, ok := sig_.(SignatureSecp256k1)
- if !ok {
- return false
- }
-
- pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256())
- if err != nil {
- return false
- }
- sig__, err := secp256k1.ParseDERSignature(sig[:], secp256k1.S256())
- if err != nil {
- return false
- }
- return sig__.Verify(Sha256(msg), pub__)
-}
-
-func (pubKey PubKeySecp256k1) String() string {
- return fmt.Sprintf("PubKeySecp256k1{%X}", pubKey[:])
-}
-
-func (pubKey PubKeySecp256k1) Equals(other PubKey) bool {
- if otherSecp, ok := other.(PubKeySecp256k1); ok {
- return bytes.Equal(pubKey[:], otherSecp[:])
- } else {
- return false
- }
-}
diff --git a/crypto/secp256k1/secp256k1.go b/crypto/secp256k1/secp256k1.go
new file mode 100644
index 00000000..c2f5d974
--- /dev/null
+++ b/crypto/secp256k1/secp256k1.go
@@ -0,0 +1,205 @@
+package secp256k1
+
+import (
+ "bytes"
+ "crypto/sha256"
+ "crypto/subtle"
+ "fmt"
+
+ secp256k1 "github.com/btcsuite/btcd/btcec"
+ amino "github.com/tendermint/go-amino"
+ "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/libs/common"
+ "golang.org/x/crypto/ripemd160"
+)
+
+//-------------------------------------
+const (
+ Secp256k1PrivKeyAminoRoute = "tendermint/PrivKeySecp256k1"
+ Secp256k1PubKeyAminoRoute = "tendermint/PubKeySecp256k1"
+ Secp256k1SignatureAminoRoute = "tendermint/SignatureSecp256k1"
+)
+
+var cdc = amino.NewCodec()
+
+func init() {
+ // NOTE: It's important that there be no conflicts here,
+ // as that would change the canonical representations,
+ // and therefore change the address.
+ // TODO: Add feature to go-amino to ensure that there
+ // are no conflicts.
+ cdc.RegisterInterface((*crypto.PubKey)(nil), nil)
+ cdc.RegisterConcrete(PubKeySecp256k1{},
+ Secp256k1PubKeyAminoRoute, nil)
+
+ cdc.RegisterInterface((*crypto.PrivKey)(nil), nil)
+ cdc.RegisterConcrete(PrivKeySecp256k1{},
+ Secp256k1PrivKeyAminoRoute, nil)
+
+ cdc.RegisterInterface((*crypto.Signature)(nil), nil)
+ cdc.RegisterConcrete(SignatureSecp256k1{},
+ Secp256k1SignatureAminoRoute, nil)
+}
+
+//-------------------------------------
+
+var _ crypto.PrivKey = PrivKeySecp256k1{}
+
+// Implements PrivKey
+type PrivKeySecp256k1 [32]byte
+
+func (privKey PrivKeySecp256k1) Bytes() []byte {
+ return cdc.MustMarshalBinaryBare(privKey)
+}
+
+func (privKey PrivKeySecp256k1) Sign(msg []byte) (crypto.Signature, error) {
+ priv__, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:])
+ sig__, err := priv__.Sign(crypto.Sha256(msg))
+ if err != nil {
+ return nil, err
+ }
+ return SignatureSecp256k1(sig__.Serialize()), nil
+}
+
+func (privKey PrivKeySecp256k1) PubKey() crypto.PubKey {
+ _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:])
+ var pub PubKeySecp256k1
+ copy(pub[:], pub__.SerializeCompressed())
+ return pub
+}
+
+// Equals - you probably don't need to use this.
+// Runs in constant time based on length of the keys.
+func (privKey PrivKeySecp256k1) Equals(other crypto.PrivKey) bool {
+ if otherSecp, ok := other.(PrivKeySecp256k1); ok {
+ return subtle.ConstantTimeCompare(privKey[:], otherSecp[:]) == 1
+ } else {
+ return false
+ }
+}
+
+/*
+// Deterministically generates new priv-key bytes from key.
+func (key PrivKeySecp256k1) Generate(index int) PrivKeySecp256k1 {
+ newBytes := cdc.BinarySha256(struct {
+ PrivKey [64]byte
+ Index int
+ }{key, index})
+ var newKey [64]byte
+ copy(newKey[:], newBytes)
+ return PrivKeySecp256k1(newKey)
+}
+*/
+
+func GenPrivKeySecp256k1() PrivKeySecp256k1 {
+ privKeyBytes := [32]byte{}
+ copy(privKeyBytes[:], crypto.CRandBytes(32))
+ priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKeyBytes[:])
+ copy(privKeyBytes[:], priv.Serialize())
+ return PrivKeySecp256k1(privKeyBytes)
+}
+
+// NOTE: secret should be the output of a KDF like bcrypt,
+// if it's derived from user input.
+func GenPrivKeySecp256k1FromSecret(secret []byte) PrivKeySecp256k1 {
+ privKey32 := crypto.Sha256(secret) // Not Ripemd160 because we want 32 bytes.
+ priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey32)
+ privKeyBytes := [32]byte{}
+ copy(privKeyBytes[:], priv.Serialize())
+ return PrivKeySecp256k1(privKeyBytes)
+}
+
+//-------------------------------------
+
+var _ crypto.PubKey = PubKeySecp256k1{}
+
+const PubKeySecp256k1Size = 33
+
+// Implements crypto.PubKey.
+// Compressed pubkey (just the x-cord),
+// prefixed with 0x02 or 0x03, depending on the y-cord.
+type PubKeySecp256k1 [PubKeySecp256k1Size]byte
+
+// Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey))
+func (pubKey PubKeySecp256k1) Address() crypto.Address {
+ hasherSHA256 := sha256.New()
+ hasherSHA256.Write(pubKey[:]) // does not error
+ sha := hasherSHA256.Sum(nil)
+
+ hasherRIPEMD160 := ripemd160.New()
+ hasherRIPEMD160.Write(sha) // does not error
+ return crypto.Address(hasherRIPEMD160.Sum(nil))
+}
+
+func (pubKey PubKeySecp256k1) Bytes() []byte {
+ bz, err := cdc.MarshalBinaryBare(pubKey)
+ if err != nil {
+ panic(err)
+ }
+ return bz
+}
+
+func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ crypto.Signature) bool {
+ // and assert same algorithm to sign and verify
+ sig, ok := sig_.(SignatureSecp256k1)
+ if !ok {
+ return false
+ }
+
+ pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256())
+ if err != nil {
+ return false
+ }
+ sig__, err := secp256k1.ParseDERSignature(sig[:], secp256k1.S256())
+ if err != nil {
+ return false
+ }
+ return sig__.Verify(crypto.Sha256(msg), pub__)
+}
+
+func (pubKey PubKeySecp256k1) String() string {
+ return fmt.Sprintf("PubKeySecp256k1{%X}", pubKey[:])
+}
+
+func (pubKey PubKeySecp256k1) Equals(other crypto.PubKey) bool {
+ if otherSecp, ok := other.(PubKeySecp256k1); ok {
+ return bytes.Equal(pubKey[:], otherSecp[:])
+ } else {
+ return false
+ }
+}
+
+//-------------------------------------
+
+var _ crypto.Signature = SignatureSecp256k1{}
+
+// Implements crypto.Signature
+type SignatureSecp256k1 []byte
+
+func (sig SignatureSecp256k1) Bytes() []byte {
+ bz, err := cdc.MarshalBinaryBare(sig)
+ if err != nil {
+ panic(err)
+ }
+ return bz
+}
+
+func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 }
+
+func (sig SignatureSecp256k1) String() string {
+ return fmt.Sprintf("/%X.../", common.Fingerprint(sig[:]))
+}
+
+func (sig SignatureSecp256k1) Equals(other crypto.Signature) bool {
+ if otherSecp, ok := other.(SignatureSecp256k1); ok {
+ return subtle.ConstantTimeCompare(sig[:], otherSecp[:]) == 1
+ } else {
+ return false
+ }
+}
+
+func SignatureSecp256k1FromBytes(data []byte) crypto.Signature {
+ sig := make(SignatureSecp256k1, len(data))
+ copy(sig[:], data)
+ return sig
+}
diff --git a/crypto/pub_key_test.go b/crypto/secp256k1/secpk256k1_test.go
similarity index 57%
rename from crypto/pub_key_test.go
rename to crypto/secp256k1/secpk256k1_test.go
index 7b856cf1..4c53871a 100644
--- a/crypto/pub_key_test.go
+++ b/crypto/secp256k1/secpk256k1_test.go
@@ -1,4 +1,4 @@
-package crypto
+package secp256k1_test
import (
"encoding/hex"
@@ -7,6 +7,9 @@ import (
"github.com/btcsuite/btcutil/base58"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+
+ "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/secp256k1"
)
type keyData struct {
@@ -28,13 +31,13 @@ func TestPubKeySecp256k1Address(t *testing.T) {
privB, _ := hex.DecodeString(d.priv)
pubB, _ := hex.DecodeString(d.pub)
addrBbz, _, _ := base58.CheckDecode(d.addr)
- addrB := Address(addrBbz)
+ addrB := crypto.Address(addrBbz)
- var priv PrivKeySecp256k1
+ var priv secp256k1.PrivKeySecp256k1
copy(priv[:], privB)
pubKey := priv.PubKey()
- pubT, _ := pubKey.(PubKeySecp256k1)
+ pubT, _ := pubKey.(secp256k1.PubKeySecp256k1)
pub := pubT[:]
addr := pubKey.Address()
@@ -43,8 +46,20 @@ func TestPubKeySecp256k1Address(t *testing.T) {
}
}
-func TestPubKeyInvalidDataProperReturnsEmpty(t *testing.T) {
- pk, err := PubKeyFromBytes([]byte("foo"))
- require.NotNil(t, err, "expecting a non-nil error")
- require.Nil(t, pk, "expecting an empty public key on error")
+func TestSignAndValidateSecp256k1(t *testing.T) {
+ privKey := secp256k1.GenPrivKeySecp256k1()
+ pubKey := privKey.PubKey()
+
+ msg := crypto.CRandBytes(128)
+ sig, err := privKey.Sign(msg)
+ require.Nil(t, err)
+
+ assert.True(t, pubKey.VerifyBytes(msg, sig))
+
+ // Mutate the signature, just one bit.
+ sigEd := sig.(secp256k1.SignatureSecp256k1)
+ sigEd[3] ^= byte(0x01)
+ sig = sigEd
+
+ assert.False(t, pubKey.VerifyBytes(msg, sig))
}
diff --git a/crypto/signature.go b/crypto/signature.go
deleted file mode 100644
index ae447da6..00000000
--- a/crypto/signature.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package crypto
-
-import (
- "fmt"
-
- "crypto/subtle"
-
- . "github.com/tendermint/tendermint/libs/common"
-)
-
-func SignatureFromBytes(pubKeyBytes []byte) (pubKey Signature, err error) {
- err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey)
- return
-}
-
-//----------------------------------------
-
-type Signature interface {
- Bytes() []byte
- IsZero() bool
- Equals(Signature) bool
-}
-
-//-------------------------------------
-
-var _ Signature = SignatureEd25519{}
-
-const SignatureEd25519Size = 64
-
-// Implements Signature
-type SignatureEd25519 [SignatureEd25519Size]byte
-
-func (sig SignatureEd25519) Bytes() []byte {
- bz, err := cdc.MarshalBinaryBare(sig)
- if err != nil {
- panic(err)
- }
- return bz
-}
-
-func (sig SignatureEd25519) IsZero() bool { return len(sig) == 0 }
-
-func (sig SignatureEd25519) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) }
-
-func (sig SignatureEd25519) Equals(other Signature) bool {
- if otherEd, ok := other.(SignatureEd25519); ok {
- return subtle.ConstantTimeCompare(sig[:], otherEd[:]) == 1
- } else {
- return false
- }
-}
-
-func SignatureEd25519FromBytes(data []byte) Signature {
- var sig SignatureEd25519
- copy(sig[:], data)
- return sig
-}
-
-//-------------------------------------
-
-var _ Signature = SignatureSecp256k1{}
-
-// Implements Signature
-type SignatureSecp256k1 []byte
-
-func (sig SignatureSecp256k1) Bytes() []byte {
- bz, err := cdc.MarshalBinaryBare(sig)
- if err != nil {
- panic(err)
- }
- return bz
-}
-
-func (sig SignatureSecp256k1) IsZero() bool { return len(sig) == 0 }
-
-func (sig SignatureSecp256k1) String() string { return fmt.Sprintf("/%X.../", Fingerprint(sig[:])) }
-
-func (sig SignatureSecp256k1) Equals(other Signature) bool {
- if otherSecp, ok := other.(SignatureSecp256k1); ok {
- return subtle.ConstantTimeCompare(sig[:], otherSecp[:]) == 1
- } else {
- return false
- }
-}
-
-func SignatureSecp256k1FromBytes(data []byte) Signature {
- sig := make(SignatureSecp256k1, len(data))
- copy(sig[:], data)
- return sig
-}
diff --git a/crypto/signature_test.go b/crypto/signature_test.go
deleted file mode 100644
index d6ae2b7a..00000000
--- a/crypto/signature_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package crypto
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestSignAndValidateEd25519(t *testing.T) {
-
- privKey := GenPrivKeyEd25519()
- pubKey := privKey.PubKey()
-
- msg := CRandBytes(128)
- sig, err := privKey.Sign(msg)
- require.Nil(t, err)
-
- // Test the signature
- assert.True(t, pubKey.VerifyBytes(msg, sig))
-
- // Mutate the signature, just one bit.
- sigEd := sig.(SignatureEd25519)
- sigEd[7] ^= byte(0x01)
- sig = sigEd
-
- assert.False(t, pubKey.VerifyBytes(msg, sig))
-}
-
-func TestSignAndValidateSecp256k1(t *testing.T) {
- privKey := GenPrivKeySecp256k1()
- pubKey := privKey.PubKey()
-
- msg := CRandBytes(128)
- sig, err := privKey.Sign(msg)
- require.Nil(t, err)
-
- assert.True(t, pubKey.VerifyBytes(msg, sig))
-
- // Mutate the signature, just one bit.
- sigEd := sig.(SignatureSecp256k1)
- sigEd[3] ^= byte(0x01)
- sig = sigEd
-
- assert.False(t, pubKey.VerifyBytes(msg, sig))
-}
diff --git a/crypto/symmetric.go b/crypto/xsalsa20Symmetric/symmetric.go
similarity index 80%
rename from crypto/symmetric.go
rename to crypto/xsalsa20Symmetric/symmetric.go
index 62379c15..c7cd5675 100644
--- a/crypto/symmetric.go
+++ b/crypto/xsalsa20Symmetric/symmetric.go
@@ -3,10 +3,13 @@ package crypto
import (
"errors"
- . "github.com/tendermint/tendermint/libs/common"
+ "github.com/tendermint/tendermint/crypto"
+ cmn "github.com/tendermint/tendermint/libs/common"
"golang.org/x/crypto/nacl/secretbox"
)
+// TODO, make this into a struct that implements crypto.Symmetric.
+
const nonceLen = 24
const secretLen = 32
@@ -15,9 +18,9 @@ const secretLen = 32
// NOTE: call crypto.MixEntropy() first.
func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte) {
if len(secret) != secretLen {
- PanicSanity(Fmt("Secret must be 32 bytes long, got len %v", len(secret)))
+ cmn.PanicSanity(cmn.Fmt("Secret must be 32 bytes long, got len %v", len(secret)))
}
- nonce := CRandBytes(nonceLen)
+ nonce := crypto.CRandBytes(nonceLen)
nonceArr := [nonceLen]byte{}
copy(nonceArr[:], nonce)
secretArr := [secretLen]byte{}
@@ -32,7 +35,7 @@ func EncryptSymmetric(plaintext []byte, secret []byte) (ciphertext []byte) {
// The ciphertext is (secretbox.Overhead + 24) bytes longer than the plaintext.
func DecryptSymmetric(ciphertext []byte, secret []byte) (plaintext []byte, err error) {
if len(secret) != secretLen {
- PanicSanity(Fmt("Secret must be 32 bytes long, got len %v", len(secret)))
+ cmn.PanicSanity(cmn.Fmt("Secret must be 32 bytes long, got len %v", len(secret)))
}
if len(ciphertext) <= secretbox.Overhead+nonceLen {
return nil, errors.New("Ciphertext is too short")
diff --git a/crypto/symmetric_test.go b/crypto/xsalsa20Symmetric/symmetric_test.go
similarity index 84%
rename from crypto/symmetric_test.go
rename to crypto/xsalsa20Symmetric/symmetric_test.go
index d92bff1a..704049e3 100644
--- a/crypto/symmetric_test.go
+++ b/crypto/xsalsa20Symmetric/symmetric_test.go
@@ -6,12 +6,13 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/tendermint/tendermint/crypto"
"golang.org/x/crypto/bcrypt"
)
func TestSimple(t *testing.T) {
- MixEntropy([]byte("someentropy"))
+ crypto.MixEntropy([]byte("someentropy"))
plaintext := []byte("sometext")
secret := []byte("somesecretoflengththirtytwo===32")
@@ -24,7 +25,7 @@ func TestSimple(t *testing.T) {
func TestSimpleWithKDF(t *testing.T) {
- MixEntropy([]byte("someentropy"))
+ crypto.MixEntropy([]byte("someentropy"))
plaintext := []byte("sometext")
secretPass := []byte("somesecret")
@@ -32,7 +33,7 @@ func TestSimpleWithKDF(t *testing.T) {
if err != nil {
t.Error(err)
}
- secret = Sha256(secret)
+ secret = crypto.Sha256(secret)
ciphertext := EncryptSymmetric(plaintext, secret)
plaintext2, err := DecryptSymmetric(ciphertext, secret)
diff --git a/docs/spec/scripts/crypto.go b/docs/spec/scripts/crypto.go
index 9ae800f8..e040f0e6 100644
--- a/docs/spec/scripts/crypto.go
+++ b/docs/spec/scripts/crypto.go
@@ -5,12 +5,12 @@ import (
"os"
amino "github.com/tendermint/go-amino"
- crypto "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
func main() {
cdc := amino.NewCodec()
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
cdc.PrintTypes(os.Stdout)
fmt.Println("")
}
diff --git a/docs/tendermint-core/configuration.md b/docs/tendermint-core/configuration.md
index 0453bdad..6b85cd38 100644
--- a/docs/tendermint-core/configuration.md
+++ b/docs/tendermint-core/configuration.md
@@ -121,10 +121,10 @@ max_num_peers = 50
max_packet_msg_payload_size = 1024
# Rate at which packets can be sent, in bytes/second
-send_rate = 512000
+send_rate = 5120000
# Rate at which packets can be received, in bytes/second
-recv_rate = 512000
+recv_rate = 5120000
# Set true to enable the peer-exchange reactor
pex = true
diff --git a/evidence/wire.go b/evidence/wire.go
index fb3a177c..c61b8618 100644
--- a/evidence/wire.go
+++ b/evidence/wire.go
@@ -2,7 +2,7 @@ package evidence
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
"github.com/tendermint/tendermint/types"
)
@@ -10,7 +10,7 @@ var cdc = amino.NewCodec()
func init() {
RegisterEvidenceMessages(cdc)
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
types.RegisterEvidences(cdc)
RegisterMockEvidences(cdc) // For testing
}
diff --git a/libs/clist/clist_test.go b/libs/clist/clist_test.go
index 6171f1a3..dbdf2f02 100644
--- a/libs/clist/clist_test.go
+++ b/libs/clist/clist_test.go
@@ -2,11 +2,12 @@ package clist
import (
"fmt"
- "math/rand"
"runtime"
"sync/atomic"
"testing"
"time"
+
+ cmn "github.com/tendermint/tendermint/libs/common"
)
func TestSmall(t *testing.T) {
@@ -131,7 +132,7 @@ func _TestGCRandom(t *testing.T) {
els = append(els, el)
}
- for _, i := range rand.Perm(numElements) {
+ for _, i := range cmn.RandPerm(numElements) {
el := els[i]
l.Remove(el)
_ = el.Next()
@@ -189,7 +190,7 @@ func TestScanRightDeleteRandom(t *testing.T) {
// Remove an element, push back an element.
for i := 0; i < numTimes; i++ {
// Pick an element to remove
- rmElIdx := rand.Intn(len(els))
+ rmElIdx := cmn.RandIntn(len(els))
rmEl := els[rmElIdx]
// Remove it
@@ -243,7 +244,7 @@ func TestWaitChan(t *testing.T) {
for i := 1; i < 100; i++ {
l.PushBack(i)
pushed++
- time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
+ time.Sleep(time.Duration(cmn.RandIntn(100)) * time.Millisecond)
}
close(done)
}()
diff --git a/libs/common/os_test.go b/libs/common/os_test.go
index 973d6890..3edd6496 100644
--- a/libs/common/os_test.go
+++ b/libs/common/os_test.go
@@ -3,17 +3,14 @@ package common
import (
"bytes"
"io/ioutil"
- "math/rand"
"os"
"testing"
- "time"
)
func TestWriteFileAtomic(t *testing.T) {
var (
- seed = rand.New(rand.NewSource(time.Now().UnixNano()))
- data = []byte(RandStr(seed.Intn(2048)))
- old = RandBytes(seed.Intn(2048))
+ data = []byte(RandStr(RandIntn(2048)))
+ old = RandBytes(RandIntn(2048))
perm os.FileMode = 0600
)
diff --git a/libs/common/random.go b/libs/common/random.go
index 389a32fc..51bfd15c 100644
--- a/libs/common/random.go
+++ b/libs/common/random.go
@@ -11,9 +11,13 @@ const (
strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters
)
-// pseudo random number generator.
-// seeded with OS randomness (crand)
-
+// Rand is a prng, that is seeded with OS randomness.
+// The OS randomness is obtained from crypto/rand, however none of the provided
+// methods are suitable for cryptographic usage.
+// They all utilize math/rand's prng internally.
+//
+// All of the methods here are suitable for concurrent use.
+// This is achieved by using a mutex lock on all of the provided methods.
type Rand struct {
sync.Mutex
rand *mrand.Rand
@@ -105,18 +109,6 @@ func RandInt63n(n int64) int64 {
return grand.Int63n(n)
}
-func RandUint16Exp() uint16 {
- return grand.Uint16Exp()
-}
-
-func RandUint32Exp() uint32 {
- return grand.Uint32Exp()
-}
-
-func RandUint64Exp() uint64 {
- return grand.Uint64Exp()
-}
-
func RandFloat32() float32 {
return grand.Float32()
}
@@ -150,8 +142,7 @@ func (r *Rand) Seed(seed int64) {
r.Unlock()
}
-// Constructs an alphanumeric string of given length.
-// It is not safe for cryptographic usage.
+// Str constructs a random alphanumeric string of given length.
func (r *Rand) Str(length int) string {
chars := []byte{}
MAIN_LOOP:
@@ -175,12 +166,10 @@ MAIN_LOOP:
return string(chars)
}
-// It is not safe for cryptographic usage.
func (r *Rand) Uint16() uint16 {
return uint16(r.Uint32() & (1<<16 - 1))
}
-// It is not safe for cryptographic usage.
func (r *Rand) Uint32() uint32 {
r.Lock()
u32 := r.rand.Uint32()
@@ -188,12 +177,10 @@ func (r *Rand) Uint32() uint32 {
return u32
}
-// It is not safe for cryptographic usage.
func (r *Rand) Uint64() uint64 {
return uint64(r.Uint32())<<32 + uint64(r.Uint32())
}
-// It is not safe for cryptographic usage.
func (r *Rand) Uint() uint {
r.Lock()
i := r.rand.Int()
@@ -201,22 +188,18 @@ func (r *Rand) Uint() uint {
return uint(i)
}
-// It is not safe for cryptographic usage.
func (r *Rand) Int16() int16 {
return int16(r.Uint32() & (1<<16 - 1))
}
-// It is not safe for cryptographic usage.
func (r *Rand) Int32() int32 {
return int32(r.Uint32())
}
-// It is not safe for cryptographic usage.
func (r *Rand) Int64() int64 {
return int64(r.Uint64())
}
-// It is not safe for cryptographic usage.
func (r *Rand) Int() int {
r.Lock()
i := r.rand.Int()
@@ -224,7 +207,6 @@ func (r *Rand) Int() int {
return i
}
-// It is not safe for cryptographic usage.
func (r *Rand) Int31() int32 {
r.Lock()
i31 := r.rand.Int31()
@@ -232,7 +214,6 @@ func (r *Rand) Int31() int32 {
return i31
}
-// It is not safe for cryptographic usage.
func (r *Rand) Int31n(n int32) int32 {
r.Lock()
i31n := r.rand.Int31n(n)
@@ -240,7 +221,6 @@ func (r *Rand) Int31n(n int32) int32 {
return i31n
}
-// It is not safe for cryptographic usage.
func (r *Rand) Int63() int64 {
r.Lock()
i63 := r.rand.Int63()
@@ -248,7 +228,6 @@ func (r *Rand) Int63() int64 {
return i63
}
-// It is not safe for cryptographic usage.
func (r *Rand) Int63n(n int64) int64 {
r.Lock()
i63n := r.rand.Int63n(n)
@@ -256,43 +235,6 @@ func (r *Rand) Int63n(n int64) int64 {
return i63n
}
-// Distributed pseudo-exponentially to test for various cases
-// It is not safe for cryptographic usage.
-func (r *Rand) Uint16Exp() uint16 {
- bits := r.Uint32() % 16
- if bits == 0 {
- return 0
- }
- n := uint16(1 << (bits - 1))
- n += uint16(r.Int31()) & ((1 << (bits - 1)) - 1)
- return n
-}
-
-// Distributed pseudo-exponentially to test for various cases
-// It is not safe for cryptographic usage.
-func (r *Rand) Uint32Exp() uint32 {
- bits := r.Uint32() % 32
- if bits == 0 {
- return 0
- }
- n := uint32(1 << (bits - 1))
- n += uint32(r.Int31()) & ((1 << (bits - 1)) - 1)
- return n
-}
-
-// Distributed pseudo-exponentially to test for various cases
-// It is not safe for cryptographic usage.
-func (r *Rand) Uint64Exp() uint64 {
- bits := r.Uint32() % 64
- if bits == 0 {
- return 0
- }
- n := uint64(1 << (bits - 1))
- n += uint64(r.Int63()) & ((1 << (bits - 1)) - 1)
- return n
-}
-
-// It is not safe for cryptographic usage.
func (r *Rand) Float32() float32 {
r.Lock()
f32 := r.rand.Float32()
@@ -300,7 +242,6 @@ func (r *Rand) Float32() float32 {
return f32
}
-// It is not safe for cryptographic usage.
func (r *Rand) Float64() float64 {
r.Lock()
f64 := r.rand.Float64()
@@ -308,13 +249,12 @@ func (r *Rand) Float64() float64 {
return f64
}
-// It is not safe for cryptographic usage.
func (r *Rand) Time() time.Time {
- return time.Unix(int64(r.Uint64Exp()), 0)
+ return time.Unix(int64(r.Uint64()), 0)
}
-// RandBytes returns n random bytes from the OS's source of entropy ie. via crypto/rand.
-// It is not safe for cryptographic usage.
+// Bytes returns n random bytes generated from the internal
+// prng.
func (r *Rand) Bytes(n int) []byte {
// cRandBytes isn't guaranteed to be fast so instead
// use random bytes generated from the internal PRNG
@@ -325,9 +265,8 @@ func (r *Rand) Bytes(n int) []byte {
return bs
}
-// RandIntn returns, as an int, a non-negative pseudo-random number in [0, n).
+// Intn returns, as an int, a uniform pseudo-random number in the range [0, n).
// It panics if n <= 0.
-// It is not safe for cryptographic usage.
func (r *Rand) Intn(n int) int {
r.Lock()
i := r.rand.Intn(n)
@@ -335,8 +274,7 @@ func (r *Rand) Intn(n int) int {
return i
}
-// RandPerm returns a pseudo-random permutation of n integers in [0, n).
-// It is not safe for cryptographic usage.
+// Perm returns a pseudo-random permutation of n integers in [0, n).
func (r *Rand) Perm(n int) []int {
r.Lock()
perm := r.rand.Perm(n)
diff --git a/libs/common/random_test.go b/libs/common/random_test.go
index b58b4a13..c59a577b 100644
--- a/libs/common/random_test.go
+++ b/libs/common/random_test.go
@@ -73,9 +73,6 @@ func testThemAll() string {
fmt.Fprintf(out, "randInt64: %d\n", RandInt64())
fmt.Fprintf(out, "randUint32: %d\n", RandUint32())
fmt.Fprintf(out, "randUint64: %d\n", RandUint64())
- fmt.Fprintf(out, "randUint16Exp: %d\n", RandUint16Exp())
- fmt.Fprintf(out, "randUint32Exp: %d\n", RandUint32Exp())
- fmt.Fprintf(out, "randUint64Exp: %d\n", RandUint64Exp())
return out.String()
}
diff --git a/libs/common/repeat_timer_test.go b/libs/common/repeat_timer_test.go
index b81720c8..f2a7b16c 100644
--- a/libs/common/repeat_timer_test.go
+++ b/libs/common/repeat_timer_test.go
@@ -1,7 +1,6 @@
package common
import (
- "math/rand"
"sync"
"testing"
"time"
@@ -131,7 +130,7 @@ func TestRepeatTimerReset(t *testing.T) {
// just random calls
for i := 0; i < 100; i++ {
- time.Sleep(time.Duration(rand.Intn(40)) * time.Millisecond)
+ time.Sleep(time.Duration(RandIntn(40)) * time.Millisecond)
timer.Reset()
}
}
diff --git a/libs/events/events_test.go b/libs/events/events_test.go
index 4995ae73..a01fbbb7 100644
--- a/libs/events/events_test.go
+++ b/libs/events/events_test.go
@@ -2,11 +2,11 @@ package events
import (
"fmt"
- "math/rand"
"testing"
"time"
"github.com/stretchr/testify/assert"
+ cmn "github.com/tendermint/tendermint/libs/common"
)
// TestAddListenerForEventFireOnce sets up an EventSwitch, subscribes a single
@@ -306,8 +306,8 @@ func TestRemoveListenersAsync(t *testing.T) {
// collect received events for event2
go sumReceivedNumbers(numbers2, doneSum2)
addListenersStress := func() {
- s1 := rand.NewSource(time.Now().UnixNano())
- r1 := rand.New(s1)
+ r1 := cmn.NewRand()
+ r1.Seed(time.Now().UnixNano())
for k := uint16(0); k < 400; k++ {
listenerNumber := r1.Intn(100) + 3
eventNumber := r1.Intn(3) + 1
@@ -317,8 +317,8 @@ func TestRemoveListenersAsync(t *testing.T) {
}
}
removeListenersStress := func() {
- s2 := rand.NewSource(time.Now().UnixNano())
- r2 := rand.New(s2)
+ r2 := cmn.NewRand()
+ r2.Seed(time.Now().UnixNano())
for k := uint16(0); k < 80; k++ {
listenerNumber := r2.Intn(100) + 3
go evsw.RemoveListener(fmt.Sprintf("listener%v", listenerNumber))
diff --git a/libs/pubsub/pubsub.go b/libs/pubsub/pubsub.go
index 4280ca1e..4c0d97e2 100644
--- a/libs/pubsub/pubsub.go
+++ b/libs/pubsub/pubsub.go
@@ -163,6 +163,8 @@ func (s *Server) Subscribe(ctx context.Context, clientID string, query Query, ou
return nil
case <-ctx.Done():
return ctx.Err()
+ case <-s.Quit():
+ return nil
}
}
@@ -190,6 +192,8 @@ func (s *Server) Unsubscribe(ctx context.Context, clientID string, query Query)
return nil
case <-ctx.Done():
return ctx.Err()
+ case <-s.Quit():
+ return nil
}
}
@@ -211,6 +215,8 @@ func (s *Server) UnsubscribeAll(ctx context.Context, clientID string) error {
return nil
case <-ctx.Done():
return ctx.Err()
+ case <-s.Quit():
+ return nil
}
}
@@ -229,6 +235,8 @@ func (s *Server) PublishWithTags(ctx context.Context, msg interface{}, tags TagM
return nil
case <-ctx.Done():
return ctx.Err()
+ case <-s.Quit():
+ return nil
}
}
diff --git a/libs/pubsub/query/Makefile b/libs/pubsub/query/Makefile
index 91030ef0..aef42b2d 100644
--- a/libs/pubsub/query/Makefile
+++ b/libs/pubsub/query/Makefile
@@ -1,10 +1,10 @@
gen_query_parser:
- @go get github.com/pointlander/peg
+ go get -u -v github.com/pointlander/peg
peg -inline -switch query.peg
fuzzy_test:
- @go get github.com/dvyukov/go-fuzz/go-fuzz
- @go get github.com/dvyukov/go-fuzz/go-fuzz-build
+ go get -u -v github.com/dvyukov/go-fuzz/go-fuzz
+ go get -u -v github.com/dvyukov/go-fuzz/go-fuzz-build
go-fuzz-build github.com/tendermint/tendermint/libs/pubsub/query/fuzz_test
go-fuzz -bin=./fuzz_test-fuzz.zip -workdir=./fuzz_test/output
diff --git a/libs/pubsub/query/query.peg.go b/libs/pubsub/query/query.peg.go
index c86e4a47..c1cc60aa 100644
--- a/libs/pubsub/query/query.peg.go
+++ b/libs/pubsub/query/query.peg.go
@@ -1,6 +1,8 @@
// nolint
package query
+//go:generate peg -inline -switch query.peg
+
import (
"fmt"
"math"
diff --git a/lite/files/wire.go b/lite/files/wire.go
index 3a207744..f45e4c63 100644
--- a/lite/files/wire.go
+++ b/lite/files/wire.go
@@ -2,11 +2,11 @@ package files
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
}
diff --git a/lite/helpers.go b/lite/helpers.go
index 695f6fb9..b98abdc8 100644
--- a/lite/helpers.go
+++ b/lite/helpers.go
@@ -4,6 +4,8 @@ import (
"time"
crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
+ "github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/tendermint/tendermint/types"
)
@@ -23,7 +25,7 @@ type ValKeys []crypto.PrivKey
func GenValKeys(n int) ValKeys {
res := make(ValKeys, n)
for i := range res {
- res[i] = crypto.GenPrivKeyEd25519()
+ res[i] = ed25519.GenPrivKeyEd25519()
}
return res
}
@@ -32,7 +34,7 @@ func GenValKeys(n int) ValKeys {
func (v ValKeys) Change(i int) ValKeys {
res := make(ValKeys, len(v))
copy(res, v)
- res[i] = crypto.GenPrivKeyEd25519()
+ res[i] = ed25519.GenPrivKeyEd25519()
return res
}
@@ -46,7 +48,7 @@ func (v ValKeys) Extend(n int) ValKeys {
func GenSecpValKeys(n int) ValKeys {
res := make(ValKeys, n)
for i := range res {
- res[i] = crypto.GenPrivKeySecp256k1()
+ res[i] = secp256k1.GenPrivKeySecp256k1()
}
return res
}
diff --git a/lite/performance_test.go b/lite/performance_test.go
index 8cd522cb..3b805a41 100644
--- a/lite/performance_test.go
+++ b/lite/performance_test.go
@@ -2,13 +2,12 @@ package lite
import (
"fmt"
- "math/rand"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
-
+ cmn "github.com/tendermint/tendermint/libs/common"
liteErr "github.com/tendermint/tendermint/lite/errors"
)
@@ -280,7 +279,11 @@ func BenchmarkMemStoreProviderGetByHeightBinarySearch1000(b *testing.B) {
benchmarkMemStoreProvidergetByHeight(b, fcs1000, h1000, binarySearch)
}
-var rng = rand.New(rand.NewSource(10))
+var rng = cmn.NewRand()
+
+func init() {
+ rng.Seed(10)
+}
func benchmarkMemStoreProvidergetByHeight(b *testing.B, fcs []FullCommit, fHeights []int64, algo algo) {
lazyGenerateFullCommits(b)
diff --git a/node/node.go b/node/node.go
index 9f6428ec..1758d5a2 100644
--- a/node/node.go
+++ b/node/node.go
@@ -13,6 +13,7 @@ import (
amino "github.com/tendermint/go-amino"
abci "github.com/tendermint/tendermint/abci/types"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
@@ -20,7 +21,6 @@ import (
bc "github.com/tendermint/tendermint/blockchain"
cfg "github.com/tendermint/tendermint/config"
cs "github.com/tendermint/tendermint/consensus"
- "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/evidence"
mempl "github.com/tendermint/tendermint/mempool"
"github.com/tendermint/tendermint/p2p"
@@ -197,7 +197,7 @@ func NewNode(config *cfg.Config,
var (
// TODO: persist this key so external signer
// can actually authenticate us
- privKey = crypto.GenPrivKeyEd25519()
+ privKey = ed25519.GenPrivKeyEd25519()
pvsc = privval.NewSocketPV(
logger.With("module", "privval"),
config.PrivValidatorListenAddr,
@@ -486,9 +486,16 @@ func (n *Node) OnStop() {
n.BaseService.OnStop()
n.Logger.Info("Stopping Node")
+
+ // first stop the non-reactor services
+ n.eventBus.Stop()
+ n.indexerService.Stop()
+
+ // now stop the reactors
// TODO: gracefully disconnect from peers.
n.sw.Stop()
+ // finally stop the listeners / external services
for _, l := range n.rpcListeners {
n.Logger.Info("Closing rpc listener", "listener", l)
if err := l.Close(); err != nil {
@@ -496,9 +503,6 @@ func (n *Node) OnStop() {
}
}
- n.eventBus.Stop()
- n.indexerService.Stop()
-
if pvsc, ok := n.privValidator.(*privval.SocketPV); ok {
if err := pvsc.Stop(); err != nil {
n.Logger.Error("Error stopping priv validator socket client", "err", err)
diff --git a/node/node_test.go b/node/node_test.go
index 80f6f02c..ca074e1b 100644
--- a/node/node_test.go
+++ b/node/node_test.go
@@ -2,6 +2,9 @@ package node
import (
"context"
+ "fmt"
+ "os"
+ "syscall"
"testing"
"time"
@@ -43,6 +46,13 @@ func TestNodeStartStop(t *testing.T) {
select {
case <-n.Quit():
case <-time.After(5 * time.Second):
+ pid := os.Getpid()
+ p, err := os.FindProcess(pid)
+ if err != nil {
+ panic(err)
+ }
+ err = p.Signal(syscall.SIGABRT)
+ fmt.Println(err)
t.Fatal("timed out waiting for shutdown")
}
}
diff --git a/node/wire.go b/node/wire.go
index 8b3ae895..3bd6de2f 100644
--- a/node/wire.go
+++ b/node/wire.go
@@ -2,11 +2,11 @@ package node
import (
amino "github.com/tendermint/go-amino"
- crypto "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
}
diff --git a/p2p/conn/secret_connection_test.go b/p2p/conn/secret_connection_test.go
index 7274dfaf..70c79e18 100644
--- a/p2p/conn/secret_connection_test.go
+++ b/p2p/conn/secret_connection_test.go
@@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
)
@@ -35,9 +35,9 @@ func makeKVStoreConnPair() (fooConn, barConn kvstoreConn) {
func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection) {
var fooConn, barConn = makeKVStoreConnPair()
- var fooPrvKey = crypto.GenPrivKeyEd25519()
+ var fooPrvKey = ed25519.GenPrivKeyEd25519()
var fooPubKey = fooPrvKey.PubKey()
- var barPrvKey = crypto.GenPrivKeyEd25519()
+ var barPrvKey = ed25519.GenPrivKeyEd25519()
var barPubKey = barPrvKey.PubKey()
// Make connections from both sides in parallel.
@@ -105,7 +105,7 @@ func TestSecretConnectionReadWrite(t *testing.T) {
genNodeRunner := func(id string, nodeConn kvstoreConn, nodeWrites []string, nodeReads *[]string) cmn.Task {
return func(_ int) (interface{}, error, bool) {
// Initiate cryptographic private key and secret connection trhough nodeConn.
- nodePrvKey := crypto.GenPrivKeyEd25519()
+ nodePrvKey := ed25519.GenPrivKeyEd25519()
nodeSecretConn, err := MakeSecretConnection(nodeConn, nodePrvKey)
if err != nil {
t.Errorf("Failed to establish SecretConnection for node: %v", err)
diff --git a/p2p/conn/wire.go b/p2p/conn/wire.go
index 3182fde3..4bd778c7 100644
--- a/p2p/conn/wire.go
+++ b/p2p/conn/wire.go
@@ -2,12 +2,12 @@ package conn
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc *amino.Codec = amino.NewCodec()
func init() {
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
RegisterPacket(cdc)
}
diff --git a/p2p/key.go b/p2p/key.go
index 9548d34f..d8054684 100644
--- a/p2p/key.go
+++ b/p2p/key.go
@@ -7,6 +7,7 @@ import (
"io/ioutil"
crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
)
@@ -70,7 +71,7 @@ func LoadNodeKey(filePath string) (*NodeKey, error) {
}
func genNodeKey(filePath string) (*NodeKey, error) {
- privKey := crypto.GenPrivKeyEd25519()
+ privKey := ed25519.GenPrivKeyEd25519()
nodeKey := &NodeKey{
PrivKey: privKey,
}
diff --git a/p2p/peer_set_test.go b/p2p/peer_set_test.go
index aa63ef94..a6a76f27 100644
--- a/p2p/peer_set_test.go
+++ b/p2p/peer_set_test.go
@@ -1,14 +1,13 @@
package p2p
import (
- "math/rand"
"net"
"sync"
"testing"
"github.com/stretchr/testify/assert"
- crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
)
@@ -18,11 +17,11 @@ func randPeer(ip net.IP) *peer {
ip = net.IP{127, 0, 0, 1}
}
- nodeKey := NodeKey{PrivKey: crypto.GenPrivKeyEd25519()}
+ nodeKey := NodeKey{PrivKey: ed25519.GenPrivKeyEd25519()}
p := &peer{
nodeInfo: NodeInfo{
ID: nodeKey.ID(),
- ListenAddr: cmn.Fmt("%v.%v.%v.%v:26656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256),
+ ListenAddr: cmn.Fmt("%v.%v.%v.%v:26656", cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256, cmn.RandInt()%256),
},
}
diff --git a/p2p/peer_test.go b/p2p/peer_test.go
index 281b218d..edfc5cf6 100644
--- a/p2p/peer_test.go
+++ b/p2p/peer_test.go
@@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require"
crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
@@ -23,7 +24,7 @@ func TestPeerBasic(t *testing.T) {
assert, require := assert.New(t), require.New(t)
// simulate remote peer
- rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: cfg}
+ rp := &remotePeer{PrivKey: ed25519.GenPrivKeyEd25519(), Config: cfg}
rp.Start()
defer rp.Stop()
@@ -49,7 +50,7 @@ func TestPeerSend(t *testing.T) {
config := cfg
// simulate remote peer
- rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: config}
+ rp := &remotePeer{PrivKey: ed25519.GenPrivKeyEd25519(), Config: config}
rp.Start()
defer rp.Stop()
@@ -74,7 +75,7 @@ func createOutboundPeerAndPerformHandshake(
{ID: testCh, Priority: 1},
}
reactorsByCh := map[byte]Reactor{testCh: NewTestReactor(chDescs, true)}
- pk := crypto.GenPrivKeyEd25519()
+ pk := ed25519.GenPrivKeyEd25519()
pc, err := newOutboundPeerConn(addr, config, false, pk)
if err != nil {
return nil, err
diff --git a/p2p/pex/addrbook_test.go b/p2p/pex/addrbook_test.go
index dd983f76..0f1cd55a 100644
--- a/p2p/pex/addrbook_test.go
+++ b/p2p/pex/addrbook_test.go
@@ -4,14 +4,13 @@ import (
"encoding/hex"
"fmt"
"io/ioutil"
- "math/rand"
"os"
"testing"
"github.com/stretchr/testify/assert"
- "github.com/tendermint/tendermint/p2p"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
+ "github.com/tendermint/tendermint/p2p"
)
func createTempFileName(prefix string) string {
@@ -202,12 +201,12 @@ func randNetAddressPairs(t *testing.T, n int) []netAddressPair {
func randIPv4Address(t *testing.T) *p2p.NetAddress {
for {
ip := fmt.Sprintf("%v.%v.%v.%v",
- rand.Intn(254)+1,
- rand.Intn(255),
- rand.Intn(255),
- rand.Intn(255),
+ cmn.RandIntn(254)+1,
+ cmn.RandIntn(255),
+ cmn.RandIntn(255),
+ cmn.RandIntn(255),
)
- port := rand.Intn(65535-1) + 1
+ port := cmn.RandIntn(65535-1) + 1
id := p2p.ID(hex.EncodeToString(cmn.RandBytes(p2p.IDByteLength)))
idAddr := p2p.IDAddressString(id, fmt.Sprintf("%v:%v", ip, port))
addr, err := p2p.NewNetAddressString(idAddr)
diff --git a/p2p/pex/pex_reactor_test.go b/p2p/pex/pex_reactor_test.go
index 629c9397..d7837133 100644
--- a/p2p/pex/pex_reactor_test.go
+++ b/p2p/pex/pex_reactor_test.go
@@ -13,6 +13,7 @@ import (
"github.com/stretchr/testify/require"
crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
@@ -355,7 +356,7 @@ func newMockPeer() mockPeer {
_, netAddr := p2p.CreateRoutableAddr()
mp := mockPeer{
addr: netAddr,
- pubKey: crypto.GenPrivKeyEd25519().PubKey(),
+ pubKey: ed25519.GenPrivKeyEd25519().PubKey(),
}
mp.BaseService = cmn.NewBaseService(nil, "MockPeer", mp)
mp.Start()
diff --git a/p2p/switch_test.go b/p2p/switch_test.go
index 97539112..8fe56972 100644
--- a/p2p/switch_test.go
+++ b/p2p/switch_test.go
@@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/config"
@@ -259,7 +259,7 @@ func TestSwitchStopsNonPersistentPeerOnError(t *testing.T) {
defer sw.Stop()
// simulate remote peer
- rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: cfg}
+ rp := &remotePeer{PrivKey: ed25519.GenPrivKeyEd25519(), Config: cfg}
rp.Start()
defer rp.Stop()
@@ -289,7 +289,7 @@ func TestSwitchReconnectsToPersistentPeer(t *testing.T) {
defer sw.Stop()
// simulate remote peer
- rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: cfg}
+ rp := &remotePeer{PrivKey: ed25519.GenPrivKeyEd25519(), Config: cfg}
rp.Start()
defer rp.Stop()
@@ -319,7 +319,7 @@ func TestSwitchReconnectsToPersistentPeer(t *testing.T) {
// simulate another remote peer
rp = &remotePeer{
- PrivKey: crypto.GenPrivKeyEd25519(),
+ PrivKey: ed25519.GenPrivKeyEd25519(),
Config: cfg,
// Use different interface to prevent duplicate IP filter, this will break
// beyond two peers.
diff --git a/p2p/test_util.go b/p2p/test_util.go
index 467532f0..37c0ba3c 100644
--- a/p2p/test_util.go
+++ b/p2p/test_util.go
@@ -4,7 +4,7 @@ import (
"fmt"
"net"
- crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
@@ -135,7 +135,7 @@ func MakeSwitch(cfg *config.P2PConfig, i int, network, version string, initSwitc
// new switch, add reactors
// TODO: let the config be passed in?
nodeKey := &NodeKey{
- PrivKey: crypto.GenPrivKeyEd25519(),
+ PrivKey: ed25519.GenPrivKeyEd25519(),
}
sw := NewSwitch(cfg)
sw.SetLogger(log.TestingLogger())
diff --git a/p2p/wire.go b/p2p/wire.go
index b7ae4125..40176e3a 100644
--- a/p2p/wire.go
+++ b/p2p/wire.go
@@ -2,11 +2,11 @@ package p2p
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
}
diff --git a/privval/priv_validator.go b/privval/priv_validator.go
index 1e85bf7b..34adcef2 100644
--- a/privval/priv_validator.go
+++ b/privval/priv_validator.go
@@ -9,6 +9,7 @@ import (
"time"
"github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/types"
)
@@ -67,7 +68,7 @@ func (pv *FilePV) GetPubKey() crypto.PubKey {
// GenFilePV generates a new validator with randomly generated private key
// and sets the filePath, but does not call Save().
func GenFilePV(filePath string) *FilePV {
- privKey := crypto.GenPrivKeyEd25519()
+ privKey := ed25519.GenPrivKeyEd25519()
return &FilePV{
Address: privKey.PubKey().Address(),
PubKey: privKey.PubKey(),
diff --git a/privval/priv_validator_test.go b/privval/priv_validator_test.go
index 5889c0d6..a129e07b 100644
--- a/privval/priv_validator_test.go
+++ b/privval/priv_validator_test.go
@@ -10,8 +10,9 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
- "github.com/tendermint/tendermint/types"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
+ "github.com/tendermint/tendermint/types"
)
func TestGenLoadValidator(t *testing.T) {
@@ -47,10 +48,10 @@ func TestUnmarshalValidator(t *testing.T) {
assert, require := assert.New(t), require.New(t)
// create some fixed values
- privKey := crypto.GenPrivKeyEd25519()
+ privKey := ed25519.GenPrivKeyEd25519()
pubKey := privKey.PubKey()
addr := pubKey.Address()
- pubArray := [32]byte(pubKey.(crypto.PubKeyEd25519))
+ pubArray := [32]byte(pubKey.(ed25519.PubKeyEd25519))
pubBytes := pubArray[:]
privArray := [64]byte(privKey)
privBytes := privArray[:]
diff --git a/privval/socket.go b/privval/socket.go
index 1e8a3807..c33443ed 100644
--- a/privval/socket.go
+++ b/privval/socket.go
@@ -9,6 +9,7 @@ import (
"github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
@@ -74,7 +75,7 @@ type SocketPV struct {
connDeadline time.Duration
connHeartbeat time.Duration
connWaitTimeout time.Duration
- privKey crypto.PrivKeyEd25519
+ privKey ed25519.PrivKeyEd25519
conn net.Conn
listener net.Listener
@@ -87,7 +88,7 @@ var _ types.PrivValidator = (*SocketPV)(nil)
func NewSocketPV(
logger log.Logger,
socketAddr string,
- privKey crypto.PrivKeyEd25519,
+ privKey ed25519.PrivKeyEd25519,
) *SocketPV {
sc := &SocketPV{
addr: socketAddr,
@@ -343,7 +344,7 @@ type RemoteSigner struct {
chainID string
connDeadline time.Duration
connRetries int
- privKey crypto.PrivKeyEd25519
+ privKey ed25519.PrivKeyEd25519
privVal types.PrivValidator
conn net.Conn
@@ -354,7 +355,7 @@ func NewRemoteSigner(
logger log.Logger,
chainID, socketAddr string,
privVal types.PrivValidator,
- privKey crypto.PrivKeyEd25519,
+ privKey ed25519.PrivKeyEd25519,
) *RemoteSigner {
rs := &RemoteSigner{
addr: socketAddr,
diff --git a/privval/socket_test.go b/privval/socket_test.go
index 7bcacd6e..8f1e9a20 100644
--- a/privval/socket_test.go
+++ b/privval/socket_test.go
@@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
@@ -112,7 +112,7 @@ func TestSocketPVAcceptDeadline(t *testing.T) {
sc = NewSocketPV(
log.TestingLogger(),
"127.0.0.1:0",
- crypto.GenPrivKeyEd25519(),
+ ed25519.GenPrivKeyEd25519(),
)
)
defer sc.Stop()
@@ -129,7 +129,7 @@ func TestSocketPVDeadline(t *testing.T) {
sc = NewSocketPV(
log.TestingLogger(),
addr,
- crypto.GenPrivKeyEd25519(),
+ ed25519.GenPrivKeyEd25519(),
)
)
@@ -152,7 +152,7 @@ func TestSocketPVDeadline(t *testing.T) {
_, err = p2pconn.MakeSecretConnection(
conn,
- crypto.GenPrivKeyEd25519(),
+ ed25519.GenPrivKeyEd25519(),
)
if err == nil {
break
@@ -172,7 +172,7 @@ func TestSocketPVWait(t *testing.T) {
sc := NewSocketPV(
log.TestingLogger(),
"127.0.0.1:0",
- crypto.GenPrivKeyEd25519(),
+ ed25519.GenPrivKeyEd25519(),
)
defer sc.Stop()
@@ -214,7 +214,7 @@ func TestRemoteSignerRetry(t *testing.T) {
cmn.RandStr(12),
ln.Addr().String(),
types.NewMockPV(),
- crypto.GenPrivKeyEd25519(),
+ ed25519.GenPrivKeyEd25519(),
)
defer rs.Stop()
@@ -245,12 +245,12 @@ func testSetupSocketPair(
chainID,
addr,
privVal,
- crypto.GenPrivKeyEd25519(),
+ ed25519.GenPrivKeyEd25519(),
)
sc = NewSocketPV(
logger,
addr,
- crypto.GenPrivKeyEd25519(),
+ ed25519.GenPrivKeyEd25519(),
)
)
diff --git a/privval/wire.go b/privval/wire.go
index c42ba40d..50660ff3 100644
--- a/privval/wire.go
+++ b/privval/wire.go
@@ -2,12 +2,12 @@ package privval
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
RegisterSocketPVMsg(cdc)
}
diff --git a/rpc/client/localclient.go b/rpc/client/localclient.go
index df3daf90..b3c5e309 100644
--- a/rpc/client/localclient.go
+++ b/rpc/client/localclient.go
@@ -3,12 +3,12 @@ package client
import (
"context"
+ cmn "github.com/tendermint/tendermint/libs/common"
tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
nm "github.com/tendermint/tendermint/node"
"github.com/tendermint/tendermint/rpc/core"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/types"
- cmn "github.com/tendermint/tendermint/libs/common"
)
/*
diff --git a/rpc/core/doc.go b/rpc/core/doc.go
index d076b3ec..75f6ac82 100644
--- a/rpc/core/doc.go
+++ b/rpc/core/doc.go
@@ -39,8 +39,6 @@ curl 'localhost:26657/broadcast_tx_sync?tx="abc"'
}
```
-The first entry in the result-array (`96`) is the method this response correlates with. `96` refers to "ResultTypeBroadcastTx", see [responses.go](https://github.com/tendermint/tendermint/blob/master/rpc/core/types/responses.go) for a complete overview.
-
## JSONRPC/HTTP
JSONRPC requests can be POST'd to the root RPC endpoint via HTTP (e.g. `http://localhost:26657/`).
diff --git a/rpc/core/types/wire.go b/rpc/core/types/wire.go
index d3a31dc3..d49b977e 100644
--- a/rpc/core/types/wire.go
+++ b/rpc/core/types/wire.go
@@ -2,12 +2,12 @@ package core_types
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
"github.com/tendermint/tendermint/types"
)
func RegisterAmino(cdc *amino.Codec) {
types.RegisterEventDatas(cdc)
types.RegisterEvidences(cdc)
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
}
diff --git a/rpc/lib/rpc_test.go b/rpc/lib/rpc_test.go
index 31839dca..3d76db32 100644
--- a/rpc/lib/rpc_test.go
+++ b/rpc/lib/rpc_test.go
@@ -6,7 +6,6 @@ import (
crand "crypto/rand"
"encoding/json"
"fmt"
- "math/rand"
"net/http"
"os"
"os/exec"
@@ -206,7 +205,7 @@ func testWithHTTPClient(t *testing.T, cl client.HTTPClient) {
require.Nil(t, err)
assert.Equal(t, got3, val3)
- val4 := rand.Intn(10000)
+ val4 := cmn.RandIntn(10000)
got4, err := echoIntViaHTTP(cl, val4)
require.Nil(t, err)
assert.Equal(t, got4, val4)
@@ -370,7 +369,7 @@ func TestWSClientPingPong(t *testing.T) {
}
func randBytes(t *testing.T) []byte {
- n := rand.Intn(10) + 2
+ n := cmn.RandIntn(10) + 2
buf := make([]byte, n)
_, err := crand.Read(buf)
require.Nil(t, err)
diff --git a/scripts/slate.sh b/scripts/slate.sh
deleted file mode 100644
index e18babea..00000000
--- a/scripts/slate.sh
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-if [ "$CIRCLE_BRANCH" == "" ]; then
- echo "this script is meant to be run on CircleCI, exiting"
- echo 1
-fi
-
-# check for changes in the `rpc/core` directory
-did_rpc_change=$(git diff --name-status $CIRCLE_BRANCH origin/master | grep rpc/core)
-
-if [ "$did_rpc_change" == "" ]; then
- echo "no changes detected in rpc/core, exiting"
- exit 0
-else
- echo "changes detected in rpc/core, continuing"
-fi
-
-# only run this script on changes to rpc/core committed to develop
-if [ "$CIRCLE_BRANCH" != "master" ]; then
- echo "the branch being built isn't master, exiting"
- exit 0
-else
- echo "on master, building the RPC docs"
-fi
-
-# godoc2md used to convert the go documentation from
-# `rpc/core` into a markdown file consumed by Slate
-go get github.com/davecheney/godoc2md
-
-# slate works via forks, and we'll be committing to
-# master branch, which will trigger our fork to run
-# the `./deploy.sh` and publish via the `gh-pages` branch
-slate_repo=github.com/tendermint/slate
-slate_path="$GOPATH"/src/"$slate_repo"
-
-if [ ! -d "$slate_path" ]; then
- git clone https://"$slate_repo".git $slate_path
-fi
-
-# the main file we need to update if rpc/core changed
-destination="$slate_path"/source/index.html.md
-
-# we remove it then re-create it with the latest changes
-rm $destination
-
-header="---
-title: RPC Reference
-
-language_tabs:
- - shell
- - go
-
-toc_footers:
- - Tendermint
- - Documentation Powered by Slate
-
-search: true
----"
-
-# write header to the main slate file
-echo "$header" > "$destination"
-
-# generate a markdown from the godoc comments, using a template
-rpc_docs=$(godoc2md -template rpc/core/doc_template.txt github.com/tendermint/tendermint/rpc/core | grep -v -e "pipe.go" -e "routes.go" -e "dev.go" | sed 's$/src/target$https://github.com/tendermint/tendermint/tree/master/rpc/core$')
-
-# append core RPC docs
-echo "$rpc_docs" >> "$destination"
-
-# commit the changes
-cd $slate_path
-
-git config --global user.email "github@tendermint.com"
-git config --global user.name "tenderbot"
-
-git commit -a -m "Update tendermint RPC docs via CircleCI"
-git push -q https://${GITHUB_ACCESS_TOKEN}@github.com/tendermint/slate.git master
diff --git a/scripts/wire2amino.go b/scripts/wire2amino.go
index 867c5735..26069b50 100644
--- a/scripts/wire2amino.go
+++ b/scripts/wire2amino.go
@@ -9,7 +9,9 @@ import (
"time"
"github.com/tendermint/go-amino"
- crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
+
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/p2p"
@@ -29,9 +31,8 @@ type Genesis struct {
ConsensusParams *types.ConsensusParams `json:"consensus_params,omitempty"`
Validators []GenesisValidator `json:"validators"`
AppHash cmn.HexBytes `json:"app_hash"`
- AppStateJSON json.RawMessage `json:"app_state,omitempty"`
+ AppState json.RawMessage `json:"app_state,omitempty"`
AppOptions json.RawMessage `json:"app_options,omitempty"` // DEPRECATED
-
}
type NodeKey struct {
@@ -59,7 +60,7 @@ func convertNodeKey(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
return nil, err
}
- var privKey crypto.PrivKeyEd25519
+ var privKey ed25519.PrivKeyEd25519
copy(privKey[:], nodeKey.PrivKey.Data)
nodeKeyNew := p2p.NodeKey{privKey}
@@ -78,10 +79,10 @@ func convertPrivVal(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
return nil, err
}
- var privKey crypto.PrivKeyEd25519
+ var privKey ed25519.PrivKeyEd25519
copy(privKey[:], privVal.PrivKey.Data)
- var pubKey crypto.PubKeyEd25519
+ var pubKey ed25519.PubKeyEd25519
copy(pubKey[:], privVal.PubKey.Data)
privValNew := privval.FilePV{
@@ -112,16 +113,16 @@ func convertGenesis(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
ChainID: genesis.ChainID,
ConsensusParams: genesis.ConsensusParams,
// Validators
- AppHash: genesis.AppHash,
- AppStateJSON: genesis.AppStateJSON,
+ AppHash: genesis.AppHash,
+ AppState: genesis.AppState,
}
if genesis.AppOptions != nil {
- genesisNew.AppStateJSON = genesis.AppOptions
+ genesisNew.AppState = genesis.AppOptions
}
for _, v := range genesis.Validators {
- var pubKey crypto.PubKeyEd25519
+ var pubKey ed25519.PubKeyEd25519
copy(pubKey[:], v.PubKey.Data)
genesisNew.Validators = append(
genesisNew.Validators,
@@ -143,7 +144,7 @@ func convertGenesis(cdc *amino.Codec, jsonBytes []byte) ([]byte, error) {
func main() {
cdc := amino.NewCodec()
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
args := os.Args[1:]
if len(args) != 1 {
diff --git a/state/execution_test.go b/state/execution_test.go
index 5e0072c3..6ed42ed4 100644
--- a/state/execution_test.go
+++ b/state/execution_test.go
@@ -10,7 +10,7 @@ import (
"github.com/tendermint/tendermint/abci/example/kvstore"
abci "github.com/tendermint/tendermint/abci/types"
- crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
@@ -150,9 +150,9 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
}
func TestUpdateValidators(t *testing.T) {
- pubkey1 := crypto.GenPrivKeyEd25519().PubKey()
+ pubkey1 := ed25519.GenPrivKeyEd25519().PubKey()
val1 := types.NewValidator(pubkey1, 10)
- pubkey2 := crypto.GenPrivKeyEd25519().PubKey()
+ pubkey2 := ed25519.GenPrivKeyEd25519().PubKey()
val2 := types.NewValidator(pubkey2, 20)
testCases := []struct {
@@ -246,7 +246,7 @@ func state(nVals, height int) (State, dbm.DB) {
vals := make([]types.GenesisValidator, nVals)
for i := 0; i < nVals; i++ {
secret := []byte(fmt.Sprintf("test%d", i))
- pk := crypto.GenPrivKeyEd25519FromSecret(secret)
+ pk := ed25519.GenPrivKeyEd25519FromSecret(secret)
vals[i] = types.GenesisValidator{
pk.PubKey(), 1000, fmt.Sprintf("test%d", i),
}
diff --git a/state/state_test.go b/state/state_test.go
index bf0c910f..b70ab021 100644
--- a/state/state_test.go
+++ b/state/state_test.go
@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db"
@@ -78,7 +79,7 @@ func TestABCIResponsesSaveLoad1(t *testing.T) {
abciResponses.DeliverTx[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Tags: nil}
abciResponses.DeliverTx[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Tags: nil}
abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.Validator{
- types.TM2PB.ValidatorFromPubKeyAndPower(crypto.GenPrivKeyEd25519().PubKey(), 10),
+ types.TM2PB.ValidatorFromPubKeyAndPower(ed25519.GenPrivKeyEd25519().PubKey(), 10),
}}
saveABCIResponses(stateDB, block.Height, abciResponses)
@@ -260,7 +261,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) {
defer tearDown(t)
const height = 1
- pubkey := crypto.GenPrivKeyEd25519().PubKey()
+ pubkey := ed25519.GenPrivKeyEd25519().PubKey()
// swap the first validator with a new one ^^^ (validator set size stays the same)
header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(state, height, pubkey)
var err error
@@ -283,7 +284,7 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) {
func genValSet(size int) *types.ValidatorSet {
vals := make([]*types.Validator, size)
for i := 0; i < size; i++ {
- vals[i] = types.NewValidator(crypto.GenPrivKeyEd25519().PubKey(), 10)
+ vals[i] = types.NewValidator(ed25519.GenPrivKeyEd25519().PubKey(), 10)
}
return types.NewValidatorSet(vals)
}
@@ -370,7 +371,7 @@ func makeParams(blockBytes, blockTx, blockGas, txBytes,
}
func pk() []byte {
- return crypto.GenPrivKeyEd25519().PubKey().Bytes()
+ return ed25519.GenPrivKeyEd25519().PubKey().Bytes()
}
func TestApplyUpdates(t *testing.T) {
diff --git a/state/wire.go b/state/wire.go
index af743c7b..eeb156d6 100644
--- a/state/wire.go
+++ b/state/wire.go
@@ -2,11 +2,11 @@ package state
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
}
diff --git a/tools/tm-bench/Gopkg.lock b/tools/tm-bench/Gopkg.lock
deleted file mode 100644
index 175acb3a..00000000
--- a/tools/tm-bench/Gopkg.lock
+++ /dev/null
@@ -1,335 +0,0 @@
-# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
-
-
-[[projects]]
- branch = "master"
- name = "github.com/beorn7/perks"
- packages = ["quantile"]
- revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
-
-[[projects]]
- branch = "master"
- name = "github.com/btcsuite/btcd"
- packages = ["btcec"]
- revision = "fdfc19097e7ac6b57035062056f5b7b4638b8898"
-
-[[projects]]
- name = "github.com/davecgh/go-spew"
- packages = ["spew"]
- revision = "346938d642f2ec3594ed81d874461961cd0faa76"
- version = "v1.1.0"
-
-[[projects]]
- branch = "master"
- name = "github.com/ebuchman/fail-test"
- packages = ["."]
- revision = "95f809107225be108efcf10a3509e4ea6ceef3c4"
-
-[[projects]]
- name = "github.com/go-kit/kit"
- packages = [
- "log",
- "log/level",
- "log/term",
- "metrics",
- "metrics/discard",
- "metrics/internal/lv",
- "metrics/prometheus"
- ]
- revision = "4dc7be5d2d12881735283bcab7352178e190fc71"
- version = "v0.6.0"
-
-[[projects]]
- name = "github.com/go-logfmt/logfmt"
- packages = ["."]
- revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5"
- version = "v0.3.0"
-
-[[projects]]
- name = "github.com/go-stack/stack"
- packages = ["."]
- revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc"
- version = "v1.7.0"
-
-[[projects]]
- name = "github.com/gogo/protobuf"
- packages = [
- "gogoproto",
- "jsonpb",
- "proto",
- "protoc-gen-gogo/descriptor",
- "sortkeys",
- "types"
- ]
- revision = "1adfc126b41513cc696b209667c8656ea7aac67c"
- version = "v1.0.0"
-
-[[projects]]
- name = "github.com/golang/protobuf"
- packages = [
- "proto",
- "ptypes",
- "ptypes/any",
- "ptypes/duration",
- "ptypes/timestamp"
- ]
- revision = "925541529c1fa6821df4e44ce2723319eb2be768"
- version = "v1.0.0"
-
-[[projects]]
- branch = "master"
- name = "github.com/golang/snappy"
- packages = ["."]
- revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a"
-
-[[projects]]
- name = "github.com/gorilla/websocket"
- packages = ["."]
- revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
- version = "v1.2.0"
-
-[[projects]]
- branch = "master"
- name = "github.com/jmhodges/levigo"
- packages = ["."]
- revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9"
-
-[[projects]]
- branch = "master"
- name = "github.com/kr/logfmt"
- packages = ["."]
- revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0"
-
-[[projects]]
- name = "github.com/matttproud/golang_protobuf_extensions"
- packages = ["pbutil"]
- revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
- version = "v1.0.1"
-
-[[projects]]
- name = "github.com/pkg/errors"
- packages = ["."]
- revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
- version = "v0.8.0"
-
-[[projects]]
- branch = "master"
- name = "github.com/prometheus/client_golang"
- packages = [
- "prometheus",
- "prometheus/promhttp"
- ]
- revision = "ae27198cdd90bf12cd134ad79d1366a6cf49f632"
-
-[[projects]]
- branch = "master"
- name = "github.com/prometheus/client_model"
- packages = ["go"]
- revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c"
-
-[[projects]]
- branch = "master"
- name = "github.com/prometheus/common"
- packages = [
- "expfmt",
- "internal/bitbucket.org/ww/goautoneg",
- "model"
- ]
- revision = "7600349dcfe1abd18d72d3a1770870d9800a7801"
-
-[[projects]]
- branch = "master"
- name = "github.com/prometheus/procfs"
- packages = [
- ".",
- "internal/util",
- "nfs",
- "xfs"
- ]
- revision = "ae68e2d4c00fed4943b5f6698d504a5fe083da8a"
-
-[[projects]]
- branch = "master"
- name = "github.com/rcrowley/go-metrics"
- packages = ["."]
- revision = "e2704e165165ec55d062f5919b4b29494e9fa790"
-
-[[projects]]
- branch = "master"
- name = "github.com/syndtr/goleveldb"
- packages = [
- "leveldb",
- "leveldb/cache",
- "leveldb/comparer",
- "leveldb/errors",
- "leveldb/filter",
- "leveldb/iterator",
- "leveldb/journal",
- "leveldb/memdb",
- "leveldb/opt",
- "leveldb/storage",
- "leveldb/table",
- "leveldb/util"
- ]
- revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445"
-
-[[projects]]
- branch = "master"
- name = "github.com/tendermint/ed25519"
- packages = [
- ".",
- "edwards25519",
- "extra25519"
- ]
- revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057"
-
-[[projects]]
- name = "github.com/tendermint/go-amino"
- packages = ["."]
- revision = "2106ca61d91029c931fd54968c2bb02dc96b1412"
- version = "0.10.1"
-
-[[projects]]
- branch = "develop"
- name = "github.com/tendermint/tendermint"
- packages = [
- "abci/client",
- "abci/example/code",
- "abci/example/kvstore",
- "abci/types",
- "blockchain",
- "config",
- "consensus",
- "consensus/types",
- "crypto",
- "crypto/merkle",
- "crypto/tmhash",
- "evidence",
- "libs/autofile",
- "libs/clist",
- "libs/common",
- "libs/db",
- "libs/events",
- "libs/flowrate",
- "libs/log",
- "libs/pubsub",
- "libs/pubsub/query",
- "mempool",
- "node",
- "p2p",
- "p2p/conn",
- "p2p/pex",
- "p2p/upnp",
- "privval",
- "proxy",
- "rpc/client",
- "rpc/core",
- "rpc/core/types",
- "rpc/grpc",
- "rpc/lib",
- "rpc/lib/client",
- "rpc/lib/server",
- "rpc/lib/types",
- "state",
- "state/txindex",
- "state/txindex/kv",
- "state/txindex/null",
- "types",
- "version"
- ]
- revision = "9d81a74429e093f3167875e0145ad957874c77d1"
-
-[[projects]]
- branch = "master"
- name = "golang.org/x/crypto"
- packages = [
- "curve25519",
- "internal/subtle",
- "nacl/box",
- "nacl/secretbox",
- "openpgp/armor",
- "openpgp/errors",
- "poly1305",
- "ripemd160",
- "salsa20/salsa"
- ]
- revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602"
-
-[[projects]]
- branch = "master"
- name = "golang.org/x/net"
- packages = [
- "context",
- "http/httpguts",
- "http2",
- "http2/hpack",
- "idna",
- "internal/timeseries",
- "netutil",
- "trace"
- ]
- revision = "292b43bbf7cb8d35ddf40f8d5100ef3837cced3f"
-
-[[projects]]
- name = "golang.org/x/text"
- packages = [
- "collate",
- "collate/build",
- "internal/colltab",
- "internal/gen",
- "internal/tag",
- "internal/triegen",
- "internal/ucd",
- "language",
- "secure/bidirule",
- "transform",
- "unicode/bidi",
- "unicode/cldr",
- "unicode/norm",
- "unicode/rangetable"
- ]
- revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
- version = "v0.3.0"
-
-[[projects]]
- branch = "master"
- name = "google.golang.org/genproto"
- packages = ["googleapis/rpc/status"]
- revision = "e92b116572682a5b432ddd840aeaba2a559eeff1"
-
-[[projects]]
- name = "google.golang.org/grpc"
- packages = [
- ".",
- "balancer",
- "balancer/base",
- "balancer/roundrobin",
- "codes",
- "connectivity",
- "credentials",
- "encoding",
- "encoding/proto",
- "grpclb/grpc_lb_v1/messages",
- "grpclog",
- "internal",
- "keepalive",
- "metadata",
- "naming",
- "peer",
- "resolver",
- "resolver/dns",
- "resolver/passthrough",
- "stats",
- "status",
- "tap",
- "transport"
- ]
- revision = "d11072e7ca9811b1100b80ca0269ac831f06d024"
- version = "v1.11.3"
-
-[solve-meta]
- analyzer-name = "dep"
- analyzer-version = 1
- inputs-digest = "bc54a74ffdfc09872726fcf5c72b5df882269dc1cd949ac3fbeac9a554fc25c6"
- solver-name = "gps-cdcl"
- solver-version = 1
diff --git a/tools/tm-bench/Gopkg.toml b/tools/tm-bench/Gopkg.toml
deleted file mode 100644
index 18498cbb..00000000
--- a/tools/tm-bench/Gopkg.toml
+++ /dev/null
@@ -1,50 +0,0 @@
-# Gopkg.toml example
-#
-# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
-# for detailed Gopkg.toml documentation.
-#
-# required = ["github.com/user/thing/cmd/thing"]
-# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
-#
-# [[constraint]]
-# name = "github.com/user/project"
-# version = "1.0.0"
-#
-# [[constraint]]
-# name = "github.com/user/project2"
-# branch = "dev"
-# source = "github.com/myfork/project2"
-#
-# [[override]]
-# name = "github.com/x/y"
-# version = "2.4.0"
-#
-# [prune]
-# non-go = false
-# go-tests = true
-# unused-packages = true
-
-
-[[constraint]]
- name = "github.com/go-kit/kit"
- version = "^0.6.0"
-
-[[constraint]]
- name = "github.com/gorilla/websocket"
- version = "^1.2.0"
-
-[[constraint]]
- name = "github.com/pkg/errors"
- version = "^0.8.0"
-
-[[constraint]]
- branch = "master"
- name = "github.com/rcrowley/go-metrics"
-
-[[constraint]]
- name = "github.com/tendermint/tendermint"
- branch = "develop"
-
-[prune]
- go-tests = true
- unused-packages = true
diff --git a/tools/tm-bench/Makefile b/tools/tm-bench/Makefile
index b95aeee9..2d427dbc 100644
--- a/tools/tm-bench/Makefile
+++ b/tools/tm-bench/Makefile
@@ -1,35 +1,7 @@
DIST_DIRS := find * -type d -exec
VERSION := $(shell perl -ne '/^var version.*"([^"]+)".*$$/ && print "v$$1\n"' main.go)
-GOTOOLS = \
- github.com/mitchellh/gox \
- github.com/golang/dep/cmd/dep \
- gopkg.in/alecthomas/gometalinter.v2
-all: check get_vendor_deps build test install metalinter
-
-check: check_tools
-
-########################################
-### Tools & dependencies
-
-check_tools:
- @# https://stackoverflow.com/a/25668869
- @echo "Found tools: $(foreach tool,$(GOTOOLS_CHECK),\
- $(if $(shell which $(tool)),$(tool),$(error "No $(tool) in PATH")))"
-
-get_tools:
- @echo "--> Installing tools"
- go get -u -v $(GOTOOLS)
- @gometalinter.v2 --install
-
-update_tools:
- @echo "--> Updating tools"
- @go get -u $(GOTOOLS)
-
-get_vendor_deps:
- @rm -rf vendor/
- @echo "--> Running dep ensure"
- @dep ensure
+all: build test install
########################################
### Build
@@ -72,44 +44,6 @@ clean:
rm -f ./tm-bench
rm -rf ./dist
-########################################
-### Formatting, linting, and vetting
-
-fmt:
- @go fmt ./...
-
-metalinter:
- @echo "==> Running linter"
- gometalinter.v2 --vendor --deadline=600s --disable-all \
- --enable=maligned \
- --enable=deadcode \
- --enable=goconst \
- --enable=goimports \
- --enable=gosimple \
- --enable=ineffassign \
- --enable=megacheck \
- --enable=misspell \
- --enable=staticcheck \
- --enable=safesql \
- --enable=structcheck \
- --enable=unconvert \
- --enable=unused \
- --enable=varcheck \
- --enable=vetshadow \
- ./...
- #--enable=gas \
- #--enable=dupl \
- #--enable=errcheck \
- #--enable=gocyclo \
- #--enable=golint \ <== comments on anything exported
- #--enable=gotype \
- #--enable=interfacer \
- #--enable=unparam \
- #--enable=vet \
-
-metalinter_all:
- gometalinter.v2 --vendor --deadline=600s --enable-all --disable=lll ./...
-
# To avoid unintended conflicts with file names, always add to .PHONY
# unless there is a reason not to.
# https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
diff --git a/tools/tm-bench/README.md b/tools/tm-bench/README.md
index 81114162..000f20f3 100644
--- a/tools/tm-bench/README.md
+++ b/tools/tm-bench/README.md
@@ -51,15 +51,26 @@ with the last command being in a seperate window.
## How stats are collected
These stats are derived by having each connection send transactions at the
-specified rate (or as close as it can get) for the specified time. After the
-specified time, it iterates over all of the blocks that were created in that
-time. The average and stddev per second are computed based off of that, by
+specified rate (or as close as it can get) for the specified time.
+After the specified time, it iterates over all of the blocks that were created
+in that time.
+The average and stddev per second are computed based off of that, by
grouping the data by second.
To send transactions at the specified rate in each connection, we loop
-through the number of transactions. If its too slow, the loop stops at one second.
-If its too fast, we wait until the one second mark ends. The transactions per
-second stat is computed based off of what ends up in the block.
+through the number of transactions.
+If its too slow, the loop stops at one second.
+If its too fast, we wait until the one second mark ends.
+The transactions per second stat is computed based off of what ends up in the
+block.
+
+Note that there will be edge effects on the number of transactions in the first
+and last blocks.
+This is because transactions may start sending midway through when tendermint
+starts building the next block, so it only has half as much time to gather txs
+that tm-bench sends.
+Similarly the end of the duration will likely end mid-way through tendermint
+trying to build the next block.
Each of the connections is handled via two separate goroutines.
diff --git a/tools/tm-bench/bench_test.go b/tools/tm-bench/bench_test.go
deleted file mode 100644
index 9eaf0f7e..00000000
--- a/tools/tm-bench/bench_test.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package main
-
-import (
- "testing"
- "time"
-)
-
-func BenchmarkTimingPerTx(b *testing.B) {
- startTime := time.Now()
- endTime := startTime.Add(time.Second)
- for i := 0; i < b.N; i++ {
- if i%20 == 0 {
- if time.Now().After(endTime) {
- continue
- }
- }
- }
-}
diff --git a/tools/tm-bench/main.go b/tools/tm-bench/main.go
index 4bc67ab3..a8ede4a0 100644
--- a/tools/tm-bench/main.go
+++ b/tools/tm-bench/main.go
@@ -1,17 +1,14 @@
package main
import (
- "encoding/json"
"flag"
"fmt"
- "math"
"os"
"strings"
- "text/tabwriter"
+ "sync"
"time"
"github.com/go-kit/kit/log/term"
- metrics "github.com/rcrowley/go-metrics"
"github.com/tendermint/tendermint/libs/log"
tmrpc "github.com/tendermint/tendermint/rpc/client"
@@ -19,19 +16,14 @@ import (
var logger = log.NewNopLogger()
-type statistics struct {
- TxsThroughput metrics.Histogram `json:"txs_per_sec"`
- BlocksThroughput metrics.Histogram `json:"blocks_per_sec"`
-}
-
func main() {
- var duration, txsRate, connections, txSize int
+ var durationInt, txsRate, connections, txSize int
var verbose bool
var outputFormat, broadcastTxMethod string
flagSet := flag.NewFlagSet("tm-bench", flag.ExitOnError)
flagSet.IntVar(&connections, "c", 1, "Connections to keep open per endpoint")
- flagSet.IntVar(&duration, "T", 10, "Exit after the specified amount of time in seconds")
+ flagSet.IntVar(&durationInt, "T", 10, "Exit after the specified amount of time in seconds")
flagSet.IntVar(&txsRate, "r", 1000, "Txs per second to send in a connection")
flagSet.IntVar(&txSize, "s", 250, "The size of a transaction in bytes.")
flagSet.StringVar(&outputFormat, "output-format", "plain", "Output format: plain or json")
@@ -42,7 +34,7 @@ func main() {
fmt.Println(`Tendermint blockchain benchmarking tool.
Usage:
- tm-bench [-c 1] [-T 10] [-r 1000] [endpoints] [-output-format [-broadcast-tx-method ]]
+ tm-bench [-c 1] [-T 10] [-r 1000] [-s 250] [endpoints] [-output-format [-broadcast-tx-method ]]
Examples:
tm-bench localhost:26657`)
@@ -73,7 +65,7 @@ Examples:
}
logger = log.NewTMLoggerWithColorFn(log.NewSyncWriter(os.Stdout), colorFn)
- fmt.Printf("Running %ds test @ %s\n", duration, flagSet.Arg(0))
+ fmt.Printf("Running %ds test @ %s\n", durationInt, flagSet.Arg(0))
}
if broadcastTxMethod != "async" &&
@@ -93,10 +85,6 @@ Examples:
)
logger.Info("Latest block height", "h", initialHeight)
- // record time start
- timeStart := time.Now()
- logger.Info("Time started", "t", timeStart)
-
transacters := startTransacters(
endpoints,
connections,
@@ -104,9 +92,17 @@ Examples:
txSize,
"broadcast_tx_"+broadcastTxMethod,
)
- endTime := time.Duration(duration) * time.Second
- <-time.After(endTime)
+ // Wait until transacters have begun until we get the start time
+ timeStart := time.Now()
+ logger.Info("Time last transacter started", "t", timeStart)
+
+ duration := time.Duration(durationInt) * time.Second
+
+ timeEnd := timeStart.Add(duration)
+ logger.Info("End time for calculation", "t", timeEnd)
+
+ <-time.After(duration)
for i, t := range transacters {
t.Stop()
numCrashes := countCrashes(t.connsBroken)
@@ -115,15 +111,13 @@ Examples:
}
}
- timeStop := time.Now()
- logger.Info("Time stopped", "t", timeStop)
+ logger.Debug("Time all transacters stopped", "t", time.Now())
stats, err := calculateStatistics(
client,
initialHeight,
timeStart,
- timeStop,
- duration,
+ durationInt,
)
if err != nil {
fmt.Fprintln(os.Stderr, err)
@@ -152,90 +146,6 @@ func countCrashes(crashes []bool) int {
return count
}
-// calculateStatistics calculates the tx / second, and blocks / second based
-// off of the number the transactions and number of blocks that occurred from
-// the start block, and the end time.
-func calculateStatistics(
- client tmrpc.Client,
- minHeight int64,
- timeStart, timeStop time.Time,
- duration int,
-) (*statistics, error) {
- stats := &statistics{
- BlocksThroughput: metrics.NewHistogram(metrics.NewUniformSample(1000)),
- TxsThroughput: metrics.NewHistogram(metrics.NewUniformSample(1000)),
- }
-
- // get blocks between minHeight and last height
- // This returns max(minHeight,(last_height - 20)) to last_height
- info, err := client.BlockchainInfo(minHeight, 0)
- if err != nil {
- return nil, err
- }
-
- var (
- blockMetas = info.BlockMetas
- lastHeight = info.LastHeight
- diff = lastHeight - minHeight
- offset = len(blockMetas)
- )
-
- for offset < int(diff) {
- // get blocks between minHeight and last height
- info, err := client.BlockchainInfo(minHeight, lastHeight-int64(offset))
- if err != nil {
- return nil, err
- }
- blockMetas = append(blockMetas, info.BlockMetas...)
- offset = len(blockMetas)
- }
-
- var (
- numBlocksPerSec = make(map[int64]int64)
- numTxsPerSec = make(map[int64]int64)
- )
-
- // because during some seconds blocks won't be created...
- for i := int64(0); i < int64(duration); i++ {
- numBlocksPerSec[i] = 0
- numTxsPerSec[i] = 0
- }
-
- // iterates from max height to min height
- for _, blockMeta := range blockMetas {
- // check if block was created after timeStart
- if blockMeta.Header.Time.Before(timeStart) {
- break
- }
-
- // check if block was created before timeStop
- if blockMeta.Header.Time.After(timeStop) {
- continue
- }
- sec := secondsSinceTimeStart(timeStart, blockMeta.Header.Time)
-
- // increase number of blocks for that second
- numBlocksPerSec[sec]++
-
- // increase number of txs for that second
- numTxsPerSec[sec] += blockMeta.Header.NumTxs
- }
-
- for _, n := range numBlocksPerSec {
- stats.BlocksThroughput.Update(n)
- }
-
- for _, n := range numTxsPerSec {
- stats.TxsThroughput.Update(n)
- }
-
- return stats, nil
-}
-
-func secondsSinceTimeStart(timeStart, timePassed time.Time) int64 {
- return int64(math.Round(timePassed.Sub(timeStart).Seconds()))
-}
-
func startTransacters(
endpoints []string,
connections,
@@ -245,52 +155,21 @@ func startTransacters(
) []*transacter {
transacters := make([]*transacter, len(endpoints))
+ wg := sync.WaitGroup{}
+ wg.Add(len(endpoints))
for i, e := range endpoints {
t := newTransacter(e, connections, txsRate, txSize, broadcastTxMethod)
t.SetLogger(logger)
- if err := t.Start(); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- transacters[i] = t
+ go func(i int) {
+ defer wg.Done()
+ if err := t.Start(); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ transacters[i] = t
+ }(i)
}
+ wg.Wait()
return transacters
}
-
-func printStatistics(stats *statistics, outputFormat string) {
- if outputFormat == "json" {
- result, err := json.Marshal(struct {
- TxsThroughput float64 `json:"txs_per_sec_avg"`
- BlocksThroughput float64 `json:"blocks_per_sec_avg"`
- }{stats.TxsThroughput.Mean(), stats.BlocksThroughput.Mean()})
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- fmt.Println(string(result))
- } else {
- w := tabwriter.NewWriter(os.Stdout, 0, 0, 5, ' ', 0)
- fmt.Fprintln(w, "Stats\tAvg\tStdDev\tMax\tTotal\t")
- fmt.Fprintln(
- w,
- fmt.Sprintf(
- "Txs/sec\t%.0f\t%.0f\t%d\t%d\t",
- stats.TxsThroughput.Mean(),
- stats.TxsThroughput.StdDev(),
- stats.TxsThroughput.Max(),
- stats.TxsThroughput.Sum(),
- ),
- )
- fmt.Fprintln(
- w,
- fmt.Sprintf("Blocks/sec\t%.3f\t%.3f\t%d\t%d\t",
- stats.BlocksThroughput.Mean(),
- stats.BlocksThroughput.StdDev(),
- stats.BlocksThroughput.Max(),
- stats.BlocksThroughput.Sum(),
- ),
- )
- w.Flush()
- }
-}
diff --git a/tools/tm-bench/statistics.go b/tools/tm-bench/statistics.go
new file mode 100644
index 00000000..5a8f6057
--- /dev/null
+++ b/tools/tm-bench/statistics.go
@@ -0,0 +1,150 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "math"
+ "os"
+ "text/tabwriter"
+ "time"
+
+ metrics "github.com/rcrowley/go-metrics"
+ tmrpc "github.com/tendermint/tendermint/rpc/client"
+ "github.com/tendermint/tendermint/types"
+)
+
+type statistics struct {
+ TxsThroughput metrics.Histogram `json:"txs_per_sec"`
+ BlocksThroughput metrics.Histogram `json:"blocks_per_sec"`
+}
+
+// calculateStatistics calculates the tx / second, and blocks / second based
+// off of the number the transactions and number of blocks that occurred from
+// the start block, and the end time.
+func calculateStatistics(
+ client tmrpc.Client,
+ minHeight int64,
+ timeStart time.Time,
+ duration int,
+) (*statistics, error) {
+ timeEnd := timeStart.Add(time.Duration(duration) * time.Second)
+
+ stats := &statistics{
+ BlocksThroughput: metrics.NewHistogram(metrics.NewUniformSample(1000)),
+ TxsThroughput: metrics.NewHistogram(metrics.NewUniformSample(1000)),
+ }
+
+ var (
+ numBlocksPerSec = make(map[int64]int64)
+ numTxsPerSec = make(map[int64]int64)
+ )
+
+ // because during some seconds blocks won't be created...
+ for i := int64(0); i < int64(duration); i++ {
+ numBlocksPerSec[i] = 0
+ numTxsPerSec[i] = 0
+ }
+
+ blockMetas, err := getBlockMetas(client, minHeight, timeStart, timeEnd)
+ if err != nil {
+ return nil, err
+ }
+
+ // iterates from max height to min height
+ for _, blockMeta := range blockMetas {
+ // check if block was created after timeStart
+ if blockMeta.Header.Time.Before(timeStart) {
+ break
+ }
+
+ // check if block was created before timeEnd
+ if blockMeta.Header.Time.After(timeEnd) {
+ continue
+ }
+ sec := secondsSinceTimeStart(timeStart, blockMeta.Header.Time)
+
+ // increase number of blocks for that second
+ numBlocksPerSec[sec]++
+
+ // increase number of txs for that second
+ numTxsPerSec[sec] += blockMeta.Header.NumTxs
+ logger.Debug(fmt.Sprintf("%d txs at block height %d", blockMeta.Header.NumTxs, blockMeta.Header.Height))
+ }
+
+ for i := int64(0); i < int64(duration); i++ {
+ stats.BlocksThroughput.Update(numBlocksPerSec[i])
+ stats.TxsThroughput.Update(numTxsPerSec[i])
+ }
+
+ return stats, nil
+}
+
+func getBlockMetas(client tmrpc.Client, minHeight int64, timeStart, timeEnd time.Time) ([]*types.BlockMeta, error) {
+ // get blocks between minHeight and last height
+ // This returns max(minHeight,(last_height - 20)) to last_height
+ info, err := client.BlockchainInfo(minHeight, 0)
+ if err != nil {
+ return nil, err
+ }
+
+ var (
+ blockMetas = info.BlockMetas
+ lastHeight = info.LastHeight
+ diff = lastHeight - minHeight
+ offset = len(blockMetas)
+ )
+
+ for offset < int(diff) {
+ // get blocks between minHeight and last height
+ info, err := client.BlockchainInfo(minHeight, lastHeight-int64(offset))
+ if err != nil {
+ return nil, err
+ }
+ blockMetas = append(blockMetas, info.BlockMetas...)
+ offset = len(blockMetas)
+ }
+
+ return blockMetas, nil
+}
+
+func secondsSinceTimeStart(timeStart, timePassed time.Time) int64 {
+ return int64(math.Round(timePassed.Sub(timeStart).Seconds()))
+}
+
+func printStatistics(stats *statistics, outputFormat string) {
+ if outputFormat == "json" {
+ result, err := json.Marshal(struct {
+ TxsThroughput float64 `json:"txs_per_sec_avg"`
+ BlocksThroughput float64 `json:"blocks_per_sec_avg"`
+ }{stats.TxsThroughput.Mean(), stats.BlocksThroughput.Mean()})
+
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ fmt.Println(string(result))
+ } else {
+ w := tabwriter.NewWriter(os.Stdout, 0, 0, 5, ' ', 0)
+ fmt.Fprintln(w, "Stats\tAvg\tStdDev\tMax\tTotal\t")
+ fmt.Fprintln(
+ w,
+ fmt.Sprintf(
+ "Txs/sec\t%.0f\t%.0f\t%d\t%d\t",
+ stats.TxsThroughput.Mean(),
+ stats.TxsThroughput.StdDev(),
+ stats.TxsThroughput.Max(),
+ stats.TxsThroughput.Sum(),
+ ),
+ )
+ fmt.Fprintln(
+ w,
+ fmt.Sprintf("Blocks/sec\t%.3f\t%.3f\t%d\t%d\t",
+ stats.BlocksThroughput.Mean(),
+ stats.BlocksThroughput.StdDev(),
+ stats.BlocksThroughput.Max(),
+ stats.BlocksThroughput.Sum(),
+ ),
+ )
+ w.Flush()
+ }
+}
diff --git a/tools/tm-bench/transacter.go b/tools/tm-bench/transacter.go
index de408136..36cc761e 100644
--- a/tools/tm-bench/transacter.go
+++ b/tools/tm-bench/transacter.go
@@ -36,7 +36,8 @@ type transacter struct {
conns []*websocket.Conn
connsBroken []bool
- wg sync.WaitGroup
+ startingWg sync.WaitGroup
+ endingWg sync.WaitGroup
stopped bool
logger log.Logger
@@ -75,19 +76,22 @@ func (t *transacter) Start() error {
t.conns[i] = c
}
- t.wg.Add(2 * t.Connections)
+ t.startingWg.Add(t.Connections)
+ t.endingWg.Add(2 * t.Connections)
for i := 0; i < t.Connections; i++ {
go t.sendLoop(i)
go t.receiveLoop(i)
}
+ t.startingWg.Wait()
+
return nil
}
// Stop closes the connections.
func (t *transacter) Stop() {
t.stopped = true
- t.wg.Wait()
+ t.endingWg.Wait()
for _, c := range t.conns {
c.Close()
}
@@ -97,7 +101,7 @@ func (t *transacter) Stop() {
// `broadcast_tx_async`).
func (t *transacter) receiveLoop(connIndex int) {
c := t.conns[connIndex]
- defer t.wg.Done()
+ defer t.endingWg.Done()
for {
_, _, err := c.ReadMessage()
if err != nil {
@@ -118,6 +122,13 @@ func (t *transacter) receiveLoop(connIndex int) {
// sendLoop generates transactions at a given rate.
func (t *transacter) sendLoop(connIndex int) {
+ started := false
+ // Close the starting waitgroup, in the event that this fails to start
+ defer func() {
+ if !started {
+ t.startingWg.Done()
+ }
+ }()
c := t.conns[connIndex]
c.SetPingHandler(func(message string) error {
@@ -139,7 +150,7 @@ func (t *transacter) sendLoop(connIndex int) {
defer func() {
pingsTicker.Stop()
txsTicker.Stop()
- t.wg.Done()
+ t.endingWg.Done()
}()
// hash of the host name is a part of each tx
@@ -149,6 +160,11 @@ func (t *transacter) sendLoop(connIndex int) {
hostname = "127.0.0.1"
}
hostnameHash = md5.Sum([]byte(hostname))
+ // each transaction embeds connection index, tx number and hash of the hostname
+ // we update the tx number between successive txs
+ tx := generateTx(connIndex, txNumber, t.Size, hostnameHash)
+ txHex := make([]byte, len(tx)*2)
+ hex.Encode(txHex, tx)
for {
select {
@@ -156,18 +172,23 @@ func (t *transacter) sendLoop(connIndex int) {
startTime := time.Now()
endTime := startTime.Add(time.Second)
numTxSent := t.Rate
+ if !started {
+ t.startingWg.Done()
+ started = true
+ }
+ now := time.Now()
for i := 0; i < t.Rate; i++ {
- // each transaction embeds connection index, tx number and hash of the hostname
- tx := generateTx(connIndex, txNumber, t.Size, hostnameHash)
- paramsJSON, err := json.Marshal(map[string]interface{}{"tx": hex.EncodeToString(tx)})
+ // update tx number of the tx, and the corresponding hex
+ updateTx(tx, txHex, txNumber)
+ paramsJSON, err := json.Marshal(map[string]interface{}{"tx": txHex})
if err != nil {
fmt.Printf("failed to encode params: %v\n", err)
os.Exit(1)
}
rawParamsJSON := json.RawMessage(paramsJSON)
- c.SetWriteDeadline(time.Now().Add(sendTimeout))
+ c.SetWriteDeadline(now.Add(sendTimeout))
err = c.WriteJSON(rpctypes.RPCRequest{
JSONRPC: "2.0",
ID: "tm-bench",
@@ -182,9 +203,10 @@ func (t *transacter) sendLoop(connIndex int) {
return
}
- // Time added here is 7.13 ns/op, not significant enough to worry about
- if i%20 == 0 {
- if time.Now().After(endTime) {
+ // cache the time.Now() reads to save time.
+ if i%5 == 0 {
+ now = time.Now()
+ if now.After(endTime) {
// Plus one accounts for sending this tx
numTxSent = i + 1
break
@@ -250,3 +272,13 @@ func generateTx(connIndex int, txNumber int, txSize int, hostnameHash [md5.Size]
return tx
}
+
+// warning, mutates input byte slice
+func updateTx(tx []byte, txHex []byte, txNumber int) {
+ binary.PutUvarint(tx[8:16], uint64(txNumber))
+ hexUpdate := make([]byte, 16)
+ hex.Encode(hexUpdate, tx[8:16])
+ for i := 16; i < 32; i++ {
+ txHex[i] = hexUpdate[i-16]
+ }
+}
diff --git a/tools/tm-bench/transacter_test.go b/tools/tm-bench/transacter_test.go
new file mode 100644
index 00000000..086a43c3
--- /dev/null
+++ b/tools/tm-bench/transacter_test.go
@@ -0,0 +1,104 @@
+package main
+
+import (
+ "crypto/md5"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ "os"
+ "testing"
+ "time"
+
+ "github.com/pkg/errors"
+ "github.com/stretchr/testify/require"
+)
+
+// This test tests that the output of generate tx and update tx is consistent
+func TestGenerateTxUpdateTxConsistentency(t *testing.T) {
+ cases := []struct {
+ connIndex int
+ startingTxNumber int
+ txSize int
+ hostname string
+ numTxsToTest int
+ }{
+ {0, 0, 50, "localhost:26657", 1000},
+ {70, 300, 10000, "localhost:26657", 1000},
+ {0, 50, 100000, "localhost:26657", 1000},
+ }
+
+ for tcIndex, tc := range cases {
+ hostnameHash := md5.Sum([]byte(tc.hostname))
+ // Tx generated from update tx. This is defined outside of the loop, since we have
+ // to a have something initially to update
+ updatedTx := generateTx(tc.connIndex, tc.startingTxNumber, tc.txSize, hostnameHash)
+ updatedHex := make([]byte, len(updatedTx)*2)
+ hex.Encode(updatedHex, updatedTx)
+ for i := 0; i < tc.numTxsToTest; i++ {
+ expectedTx := generateTx(tc.connIndex, tc.startingTxNumber+i, tc.txSize, hostnameHash)
+ expectedHex := make([]byte, len(expectedTx)*2)
+ hex.Encode(expectedHex, expectedTx)
+
+ updateTx(updatedTx, updatedHex, tc.startingTxNumber+i)
+
+ // after first 32 bytes is 8 bytes of time, then purely random bytes
+ require.Equal(t, expectedTx[:32], updatedTx[:32],
+ "First 32 bytes of the txs differed. tc #%d, i #%d", tcIndex, i)
+ require.Equal(t, expectedHex[:64], updatedHex[:64],
+ "First 64 bytes of the hex differed. tc #%d, i #%d", tcIndex, i)
+ // Test the lengths of the txs are as expected
+ require.Equal(t, tc.txSize, len(expectedTx),
+ "Length of expected Tx differed. tc #%d, i #%d", tcIndex, i)
+ require.Equal(t, tc.txSize, len(updatedTx),
+ "Length of expected Tx differed. tc #%d, i #%d", tcIndex, i)
+ require.Equal(t, tc.txSize*2, len(expectedHex),
+ "Length of expected hex differed. tc #%d, i #%d", tcIndex, i)
+ require.Equal(t, tc.txSize*2, len(updatedHex),
+ "Length of updated hex differed. tc #%d, i #%d", tcIndex, i)
+ }
+ }
+}
+
+func BenchmarkIterationOfSendLoop(b *testing.B) {
+ var (
+ connIndex = 0
+ txSize = 25000
+ )
+
+ now := time.Now()
+ // something too far away to matter
+ endTime := now.Add(time.Hour)
+ txNumber := 0
+ hostnameHash := md5.Sum([]byte{0})
+ tx := generateTx(connIndex, txNumber, txSize, hostnameHash)
+ txHex := make([]byte, len(tx)*2)
+ hex.Encode(txHex, tx)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ updateTx(tx, txHex, txNumber)
+ paramsJSON, err := json.Marshal(map[string]interface{}{"tx": txHex})
+ if err != nil {
+ fmt.Printf("failed to encode params: %v\n", err)
+ os.Exit(1)
+ }
+ _ = json.RawMessage(paramsJSON)
+ _ = now.Add(sendTimeout)
+
+ if err != nil {
+ err = errors.Wrap(err,
+ fmt.Sprintf("txs send failed on connection #%d", connIndex))
+ logger.Error(err.Error())
+ return
+ }
+
+ // Cache the now operations
+ if i%5 == 0 {
+ now = time.Now()
+ if now.After(endTime) {
+ break
+ }
+ }
+
+ txNumber++
+ }
+}
diff --git a/tools/tm-monitor/Gopkg.lock b/tools/tm-monitor/Gopkg.lock
deleted file mode 100644
index 1bf318a4..00000000
--- a/tools/tm-monitor/Gopkg.lock
+++ /dev/null
@@ -1,326 +0,0 @@
-# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
-
-
-[[projects]]
- branch = "master"
- name = "github.com/beorn7/perks"
- packages = ["quantile"]
- revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
-
-[[projects]]
- branch = "master"
- name = "github.com/btcsuite/btcd"
- packages = ["btcec"]
- revision = "fdfc19097e7ac6b57035062056f5b7b4638b8898"
-
-[[projects]]
- name = "github.com/davecgh/go-spew"
- packages = ["spew"]
- revision = "346938d642f2ec3594ed81d874461961cd0faa76"
- version = "v1.1.0"
-
-[[projects]]
- name = "github.com/ebuchman/fail-test"
- packages = ["."]
- revision = "95f809107225be108efcf10a3509e4ea6ceef3c4"
-
-[[projects]]
- name = "github.com/go-kit/kit"
- packages = [
- "log",
- "log/level",
- "log/term",
- "metrics",
- "metrics/discard",
- "metrics/internal/lv",
- "metrics/prometheus"
- ]
- revision = "4dc7be5d2d12881735283bcab7352178e190fc71"
- version = "v0.6.0"
-
-[[projects]]
- name = "github.com/go-logfmt/logfmt"
- packages = ["."]
- revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5"
- version = "v0.3.0"
-
-[[projects]]
- name = "github.com/go-stack/stack"
- packages = ["."]
- revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc"
- version = "v1.7.0"
-
-[[projects]]
- name = "github.com/gogo/protobuf"
- packages = [
- "gogoproto",
- "jsonpb",
- "proto",
- "protoc-gen-gogo/descriptor",
- "sortkeys",
- "types"
- ]
- revision = "1adfc126b41513cc696b209667c8656ea7aac67c"
- version = "v1.0.0"
-
-[[projects]]
- name = "github.com/golang/protobuf"
- packages = [
- "proto",
- "ptypes",
- "ptypes/any",
- "ptypes/duration",
- "ptypes/timestamp"
- ]
- revision = "925541529c1fa6821df4e44ce2723319eb2be768"
- version = "v1.0.0"
-
-[[projects]]
- branch = "master"
- name = "github.com/golang/snappy"
- packages = ["."]
- revision = "2e65f85255dbc3072edf28d6b5b8efc472979f5a"
-
-[[projects]]
- name = "github.com/gorilla/websocket"
- packages = ["."]
- revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
- version = "v1.2.0"
-
-[[projects]]
- branch = "master"
- name = "github.com/jmhodges/levigo"
- packages = ["."]
- revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9"
-
-[[projects]]
- branch = "master"
- name = "github.com/kr/logfmt"
- packages = ["."]
- revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0"
-
-[[projects]]
- name = "github.com/matttproud/golang_protobuf_extensions"
- packages = ["pbutil"]
- revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
- version = "v1.0.1"
-
-[[projects]]
- name = "github.com/pkg/errors"
- packages = ["."]
- revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
- version = "v0.8.0"
-
-[[projects]]
- name = "github.com/pmezard/go-difflib"
- packages = ["difflib"]
- revision = "792786c7400a136282c1664665ae0a8db921c6c2"
- version = "v1.0.0"
-
-[[projects]]
- name = "github.com/prometheus/client_golang"
- packages = ["prometheus"]
- revision = "ae27198cdd90bf12cd134ad79d1366a6cf49f632"
-
-[[projects]]
- branch = "master"
- name = "github.com/prometheus/client_model"
- packages = ["go"]
- revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c"
-
-[[projects]]
- branch = "master"
- name = "github.com/prometheus/common"
- packages = [
- "expfmt",
- "internal/bitbucket.org/ww/goautoneg",
- "model"
- ]
- revision = "7600349dcfe1abd18d72d3a1770870d9800a7801"
-
-[[projects]]
- branch = "master"
- name = "github.com/prometheus/procfs"
- packages = [
- ".",
- "internal/util",
- "nfs",
- "xfs"
- ]
- revision = "ae68e2d4c00fed4943b5f6698d504a5fe083da8a"
-
-[[projects]]
- branch = "master"
- name = "github.com/rcrowley/go-metrics"
- packages = ["."]
- revision = "e2704e165165ec55d062f5919b4b29494e9fa790"
-
-[[projects]]
- name = "github.com/stretchr/testify"
- packages = [
- "assert",
- "require"
- ]
- revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
- version = "v1.2.2"
-
-[[projects]]
- branch = "master"
- name = "github.com/syndtr/goleveldb"
- packages = [
- "leveldb",
- "leveldb/cache",
- "leveldb/comparer",
- "leveldb/errors",
- "leveldb/filter",
- "leveldb/iterator",
- "leveldb/journal",
- "leveldb/memdb",
- "leveldb/opt",
- "leveldb/storage",
- "leveldb/table",
- "leveldb/util"
- ]
- revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445"
-
-[[projects]]
- branch = "master"
- name = "github.com/tendermint/ed25519"
- packages = [
- ".",
- "edwards25519",
- "extra25519"
- ]
- revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057"
-
-[[projects]]
- name = "github.com/tendermint/go-amino"
- packages = ["."]
- revision = "2106ca61d91029c931fd54968c2bb02dc96b1412"
- version = "0.10.1"
-
-[[projects]]
- name = "github.com/tendermint/tendermint"
- packages = [
- "abci/client",
- "abci/example/code",
- "abci/example/kvstore",
- "abci/types",
- "config",
- "crypto",
- "crypto/merkle",
- "crypto/tmhash",
- "libs/common",
- "libs/db",
- "libs/events",
- "libs/flowrate",
- "libs/log",
- "libs/pubsub",
- "libs/pubsub/query",
- "p2p",
- "p2p/conn",
- "p2p/upnp",
- "proxy",
- "rpc/core/types",
- "rpc/lib/client",
- "rpc/lib/server",
- "rpc/lib/types",
- "state",
- "types"
- ]
- revision = "2aa2b63cadc42cca1071c36adfd2f2ce14e1aa8f"
- version = "v0.22.3"
-
-[[projects]]
- branch = "master"
- name = "golang.org/x/crypto"
- packages = [
- "curve25519",
- "internal/subtle",
- "nacl/box",
- "nacl/secretbox",
- "openpgp/armor",
- "openpgp/errors",
- "poly1305",
- "ripemd160",
- "salsa20/salsa"
- ]
- revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602"
-
-[[projects]]
- name = "golang.org/x/net"
- packages = [
- "context",
- "http/httpguts",
- "http2",
- "http2/hpack",
- "idna",
- "internal/timeseries",
- "netutil",
- "trace"
- ]
- revision = "292b43bbf7cb8d35ddf40f8d5100ef3837cced3f"
-
-[[projects]]
- name = "golang.org/x/text"
- packages = [
- "collate",
- "collate/build",
- "internal/colltab",
- "internal/gen",
- "internal/tag",
- "internal/triegen",
- "internal/ucd",
- "language",
- "secure/bidirule",
- "transform",
- "unicode/bidi",
- "unicode/cldr",
- "unicode/norm",
- "unicode/rangetable"
- ]
- revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
- version = "v0.3.0"
-
-[[projects]]
- branch = "master"
- name = "google.golang.org/genproto"
- packages = ["googleapis/rpc/status"]
- revision = "e92b116572682a5b432ddd840aeaba2a559eeff1"
-
-[[projects]]
- name = "google.golang.org/grpc"
- packages = [
- ".",
- "balancer",
- "balancer/base",
- "balancer/roundrobin",
- "codes",
- "connectivity",
- "credentials",
- "encoding",
- "encoding/proto",
- "grpclb/grpc_lb_v1/messages",
- "grpclog",
- "internal",
- "keepalive",
- "metadata",
- "naming",
- "peer",
- "resolver",
- "resolver/dns",
- "resolver/passthrough",
- "stats",
- "status",
- "tap",
- "transport"
- ]
- revision = "d11072e7ca9811b1100b80ca0269ac831f06d024"
- version = "v1.11.3"
-
-[solve-meta]
- analyzer-name = "dep"
- analyzer-version = 1
- inputs-digest = "b8644e2f33b8c04ed76a9cda1b6d7741a0e36844fdb0ce0d68717332779bcd75"
- solver-name = "gps-cdcl"
- solver-version = 1
diff --git a/tools/tm-monitor/Gopkg.toml b/tools/tm-monitor/Gopkg.toml
deleted file mode 100644
index 5fd611d8..00000000
--- a/tools/tm-monitor/Gopkg.toml
+++ /dev/null
@@ -1,50 +0,0 @@
-# Gopkg.toml example
-#
-# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
-# for detailed Gopkg.toml documentation.
-#
-# required = ["github.com/user/thing/cmd/thing"]
-# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
-#
-# [[constraint]]
-# name = "github.com/user/project"
-# version = "1.0.0"
-#
-# [[constraint]]
-# name = "github.com/user/project2"
-# branch = "dev"
-# source = "github.com/myfork/project2"
-#
-# [[override]]
-# name = "github.com/x/y"
-# version = "2.4.0"
-#
-# [prune]
-# non-go = false
-# go-tests = true
-# unused-packages = true
-
-
-[[constraint]]
- name = "github.com/pkg/errors"
- version = "0.8.0"
-
-[[constraint]]
- branch = "master"
- name = "github.com/rcrowley/go-metrics"
-
-[[constraint]]
- name = "github.com/stretchr/testify"
- version = "1.2.1"
-
-[[constraint]]
- name = "github.com/tendermint/go-amino"
- version = "~0.10.1"
-
-[[constraint]]
- name = "github.com/tendermint/tendermint"
- version = "v0.22.3"
-
-[prune]
- go-tests = true
- unused-packages = true
diff --git a/tools/tm-monitor/monitor/monitor_test.go b/tools/tm-monitor/monitor/monitor_test.go
index b487075b..e089d338 100644
--- a/tools/tm-monitor/monitor/monitor_test.go
+++ b/tools/tm-monitor/monitor/monitor_test.go
@@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/go-amino"
- crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
mock "github.com/tendermint/tendermint/tools/tm-monitor/mock"
monitor "github.com/tendermint/tendermint/tools/tm-monitor/monitor"
@@ -60,7 +60,7 @@ func createValidatorNode(t *testing.T) (n *monitor.Node, emMock *mock.EventMeter
emMock = &mock.EventMeter{}
stubs := make(map[string]interface{})
- pubKey := crypto.GenPrivKeyEd25519().PubKey()
+ pubKey := ed25519.GenPrivKeyEd25519().PubKey()
stubs["validators"] = ctypes.ResultValidators{BlockHeight: blockHeight, Validators: []*tmtypes.Validator{tmtypes.NewValidator(pubKey, 0)}}
stubs["status"] = ctypes.ResultStatus{ValidatorInfo: ctypes.ValidatorInfo{PubKey: pubKey}}
cdc := amino.NewCodec()
diff --git a/tools/tm-monitor/monitor/node_test.go b/tools/tm-monitor/monitor/node_test.go
index e97b2de4..449abcc9 100644
--- a/tools/tm-monitor/monitor/node_test.go
+++ b/tools/tm-monitor/monitor/node_test.go
@@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/tendermint/go-amino"
- crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
em "github.com/tendermint/tendermint/tools/tm-monitor/eventmeter"
mock "github.com/tendermint/tendermint/tools/tm-monitor/mock"
@@ -78,7 +78,7 @@ func startValidatorNode(t *testing.T) (n *monitor.Node, emMock *mock.EventMeter)
emMock = &mock.EventMeter{}
stubs := make(map[string]interface{})
- pubKey := crypto.GenPrivKeyEd25519().PubKey()
+ pubKey := ed25519.GenPrivKeyEd25519().PubKey()
stubs["validators"] = ctypes.ResultValidators{BlockHeight: blockHeight, Validators: []*tmtypes.Validator{tmtypes.NewValidator(pubKey, 0)}}
stubs["status"] = ctypes.ResultStatus{ValidatorInfo: ctypes.ValidatorInfo{PubKey: pubKey}}
cdc := amino.NewCodec()
diff --git a/types/block.go b/types/block.go
index bc018ee8..e23fd71d 100644
--- a/types/block.go
+++ b/types/block.go
@@ -107,6 +107,7 @@ func (b *Block) Hash() cmn.HexBytes {
// MakePartSet returns a PartSet containing parts of a serialized block.
// This is the form in which the block is gossipped to peers.
+// CONTRACT: partSize is greater than zero.
func (b *Block) MakePartSet(partSize int) *PartSet {
if b == nil {
return nil
@@ -208,7 +209,7 @@ type Header struct {
// Hash returns the hash of the header.
// Returns nil if ValidatorHash is missing,
// since a Header is not valid unless there is
-// a ValidaotrsHash (corresponding to the validator set).
+// a ValidatorsHash (corresponding to the validator set).
func (h *Header) Hash() cmn.HexBytes {
if h == nil || len(h.ValidatorsHash) == 0 {
return nil
@@ -392,6 +393,9 @@ func (commit *Commit) ValidateBasic() error {
// Hash returns the hash of the commit
func (commit *Commit) Hash() cmn.HexBytes {
+ if commit == nil {
+ return nil
+ }
if commit.hash == nil {
bs := make([]merkle.Hasher, len(commit.Precommits))
for i, precommit := range commit.Precommits {
diff --git a/types/block_test.go b/types/block_test.go
index 0948e7b2..1d27a774 100644
--- a/types/block_test.go
+++ b/types/block_test.go
@@ -10,7 +10,25 @@ import (
cmn "github.com/tendermint/tendermint/libs/common"
)
-func TestValidateBlock(t *testing.T) {
+func TestBlockAddEvidence(t *testing.T) {
+ txs := []Tx{Tx("foo"), Tx("bar")}
+ lastID := makeBlockIDRandom()
+ h := int64(3)
+
+ voteSet, valSet, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
+ commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
+ require.NoError(t, err)
+
+ block := MakeBlock(h, txs, commit)
+ require.NotNil(t, block)
+
+ ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
+ block.AddEvidence([]Evidence{ev})
+}
+
+func TestBlockValidateBasic(t *testing.T) {
+ require.Error(t, (*Block)(nil).ValidateBasic())
+
txs := []Tx{Tx("foo"), Tx("bar")}
lastID := makeBlockIDRandom()
h := int64(3)
@@ -57,6 +75,59 @@ func TestValidateBlock(t *testing.T) {
block.DataHash = cmn.RandBytes(len(block.DataHash))
err = block.ValidateBasic()
require.Error(t, err)
+
+ // tamper with evidence
+ block = MakeBlock(h, txs, commit)
+ block.EvidenceHash = []byte("something else")
+ err = block.ValidateBasic()
+ require.Error(t, err)
+}
+
+func TestBlockHash(t *testing.T) {
+ assert.Nil(t, (*Block)(nil).Hash())
+ assert.Nil(t, MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).Hash())
+}
+
+func TestBlockMakePartSet(t *testing.T) {
+ assert.Nil(t, (*Block)(nil).MakePartSet(2))
+
+ partSet := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).MakePartSet(1024)
+ assert.NotNil(t, partSet)
+ assert.Equal(t, 1, partSet.Total())
+}
+
+func TestBlockHashesTo(t *testing.T) {
+ assert.False(t, (*Block)(nil).HashesTo(nil))
+
+ lastID := makeBlockIDRandom()
+ h := int64(3)
+ voteSet, valSet, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
+ commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
+ require.NoError(t, err)
+
+ block := MakeBlock(h, []Tx{Tx("Hello World")}, commit)
+ block.ValidatorsHash = valSet.Hash()
+ assert.False(t, block.HashesTo([]byte{}))
+ assert.False(t, block.HashesTo([]byte("something else")))
+ assert.True(t, block.HashesTo(block.Hash()))
+}
+
+func TestBlockSize(t *testing.T) {
+ size := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).Size()
+ if size <= 0 {
+ t.Fatal("Size of the block is zero or negative")
+ }
+}
+
+func TestBlockString(t *testing.T) {
+ assert.Equal(t, "nil-Block", (*Block)(nil).String())
+ assert.Equal(t, "nil-Block", (*Block)(nil).StringIndented(""))
+ assert.Equal(t, "nil-Block", (*Block)(nil).StringShort())
+
+ block := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil)
+ assert.NotEqual(t, "nil-Block", block.String())
+ assert.NotEqual(t, "nil-Block", block.StringIndented(""))
+ assert.NotEqual(t, "nil-Block", block.StringShort())
}
func makeBlockIDRandom() BlockID {
@@ -86,3 +157,61 @@ func TestNilDataHashDoesntCrash(t *testing.T) {
assert.Equal(t, []byte((*Data)(nil).Hash()), nilBytes)
assert.Equal(t, []byte(new(Data).Hash()), nilBytes)
}
+
+func TestCommit(t *testing.T) {
+ lastID := makeBlockIDRandom()
+ h := int64(3)
+ voteSet, _, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
+ commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
+ require.NoError(t, err)
+
+ assert.NotNil(t, commit.FirstPrecommit())
+ assert.Equal(t, h-1, commit.Height())
+ assert.Equal(t, 1, commit.Round())
+ assert.Equal(t, VoteTypePrecommit, commit.Type())
+ if commit.Size() <= 0 {
+ t.Fatalf("commit %v has a zero or negative size: %d", commit, commit.Size())
+ }
+
+ require.NotNil(t, commit.BitArray())
+ assert.Equal(t, cmn.NewBitArray(10).Size(), commit.BitArray().Size())
+
+ assert.Equal(t, voteSet.GetByIndex(0), commit.GetByIndex(0))
+ assert.True(t, commit.IsCommit())
+}
+
+func TestCommitValidateBasic(t *testing.T) {
+ commit := randCommit()
+ assert.NoError(t, commit.ValidateBasic())
+
+ // nil precommit is OK
+ commit = randCommit()
+ commit.Precommits[0] = nil
+ assert.NoError(t, commit.ValidateBasic())
+
+ // tamper with types
+ commit = randCommit()
+ commit.Precommits[0].Type = VoteTypePrevote
+ assert.Error(t, commit.ValidateBasic())
+
+ // tamper with height
+ commit = randCommit()
+ commit.Precommits[0].Height = int64(100)
+ assert.Error(t, commit.ValidateBasic())
+
+ // tamper with round
+ commit = randCommit()
+ commit.Precommits[0].Round = 100
+ assert.Error(t, commit.ValidateBasic())
+}
+
+func randCommit() *Commit {
+ lastID := makeBlockIDRandom()
+ h := int64(3)
+ voteSet, _, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
+ commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
+ if err != nil {
+ panic(err)
+ }
+ return commit
+}
diff --git a/types/event_buffer.go b/types/event_buffer.go
deleted file mode 100644
index 18b41014..00000000
--- a/types/event_buffer.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package types
-
-// Interface assertions
-var _ TxEventPublisher = (*TxEventBuffer)(nil)
-
-// TxEventBuffer is a buffer of events, which uses a slice to temporarily store
-// events.
-type TxEventBuffer struct {
- next TxEventPublisher
- capacity int
- events []EventDataTx
-}
-
-// NewTxEventBuffer accepts a TxEventPublisher and returns a new buffer with the given
-// capacity.
-func NewTxEventBuffer(next TxEventPublisher, capacity int) *TxEventBuffer {
- return &TxEventBuffer{
- next: next,
- capacity: capacity,
- events: make([]EventDataTx, 0, capacity),
- }
-}
-
-// Len returns the number of events cached.
-func (b TxEventBuffer) Len() int {
- return len(b.events)
-}
-
-// PublishEventTx buffers an event to be fired upon finality.
-func (b *TxEventBuffer) PublishEventTx(e EventDataTx) error {
- b.events = append(b.events, e)
- return nil
-}
-
-// Flush publishes events by running next.PublishWithTags on all cached events.
-// Blocks. Clears cached events.
-func (b *TxEventBuffer) Flush() error {
- for _, e := range b.events {
- err := b.next.PublishEventTx(e)
- if err != nil {
- return err
- }
- }
-
- // Clear out the elements and set the length to 0
- // but maintain the underlying slice's capacity.
- // See Issue https://github.com/tendermint/tendermint/issues/1189
- b.events = b.events[:0]
- return nil
-}
diff --git a/types/event_buffer_test.go b/types/event_buffer_test.go
deleted file mode 100644
index 74ae9da2..00000000
--- a/types/event_buffer_test.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package types
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-type eventBusMock struct{}
-
-func (eventBusMock) PublishEventTx(e EventDataTx) error {
- return nil
-}
-
-func TestEventBuffer(t *testing.T) {
- b := NewTxEventBuffer(eventBusMock{}, 1)
- b.PublishEventTx(EventDataTx{})
- assert.Equal(t, 1, b.Len())
- b.Flush()
- assert.Equal(t, 0, b.Len())
-}
diff --git a/types/event_bus.go b/types/event_bus.go
index 54fc60c7..b4965fee 100644
--- a/types/event_bus.go
+++ b/types/event_bus.go
@@ -4,9 +4,9 @@ import (
"context"
"fmt"
- tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
+ tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
)
const defaultCapacity = 0
@@ -49,7 +49,7 @@ func (b *EventBus) OnStart() error {
}
func (b *EventBus) OnStop() {
- b.pubsub.OnStop()
+ b.pubsub.Stop()
}
func (b *EventBus) Subscribe(ctx context.Context, subscriber string, query tmpubsub.Query, out chan<- interface{}) error {
diff --git a/types/event_bus_test.go b/types/event_bus_test.go
index 81903004..768b5b32 100644
--- a/types/event_bus_test.go
+++ b/types/event_bus_test.go
@@ -3,7 +3,6 @@ package types
import (
"context"
"fmt"
- "math/rand"
"testing"
"time"
@@ -11,9 +10,9 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
+ cmn "github.com/tendermint/tendermint/libs/common"
tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
tmquery "github.com/tendermint/tendermint/libs/pubsub/query"
- cmn "github.com/tendermint/tendermint/libs/common"
)
func TestEventBusPublishEventTx(t *testing.T) {
@@ -59,6 +58,64 @@ func TestEventBusPublishEventTx(t *testing.T) {
}
}
+func TestEventBusPublish(t *testing.T) {
+ eventBus := NewEventBus()
+ err := eventBus.Start()
+ require.NoError(t, err)
+ defer eventBus.Stop()
+
+ eventsCh := make(chan interface{})
+ err = eventBus.Subscribe(context.Background(), "test", tmquery.Empty{}, eventsCh)
+ require.NoError(t, err)
+
+ const numEventsExpected = 14
+ done := make(chan struct{})
+ go func() {
+ numEvents := 0
+ for range eventsCh {
+ numEvents++
+ if numEvents >= numEventsExpected {
+ close(done)
+ }
+ }
+ }()
+
+ err = eventBus.Publish(EventNewBlockHeader, EventDataNewBlockHeader{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventNewBlock(EventDataNewBlock{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventNewBlockHeader(EventDataNewBlockHeader{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventVote(EventDataVote{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventProposalHeartbeat(EventDataProposalHeartbeat{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventNewRoundStep(EventDataRoundState{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventTimeoutPropose(EventDataRoundState{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventTimeoutWait(EventDataRoundState{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventNewRound(EventDataRoundState{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventCompleteProposal(EventDataRoundState{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventPolka(EventDataRoundState{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventUnlock(EventDataRoundState{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventRelock(EventDataRoundState{})
+ require.NoError(t, err)
+ err = eventBus.PublishEventLock(EventDataRoundState{})
+ require.NoError(t, err)
+
+ select {
+ case <-done:
+ case <-time.After(1 * time.Second):
+ t.Fatalf("expected to receive %d events after 1 sec.", numEventsExpected)
+ }
+}
+
func BenchmarkEventBus(b *testing.B) {
benchmarks := []struct {
name string
@@ -92,7 +149,7 @@ func BenchmarkEventBus(b *testing.B) {
func benchmarkEventBus(numClients int, randQueries bool, randEvents bool, b *testing.B) {
// for random* functions
- rand.Seed(time.Now().Unix())
+ cmn.Seed(time.Now().Unix())
eventBus := NewEventBusWithBufferCapacity(0) // set buffer capacity to 0 so we are not testing cache
eventBus.Start()
@@ -126,11 +183,7 @@ func benchmarkEventBus(numClients int, randQueries bool, randEvents bool, b *tes
}
}
-var events = []string{EventBond,
- EventUnbond,
- EventRebond,
- EventDupeout,
- EventFork,
+var events = []string{
EventNewBlock,
EventNewBlockHeader,
EventNewRound,
@@ -145,14 +198,10 @@ var events = []string{EventBond,
EventVote}
func randEvent() string {
- return events[rand.Intn(len(events))]
+ return events[cmn.RandIntn(len(events))]
}
-var queries = []tmpubsub.Query{EventQueryBond,
- EventQueryUnbond,
- EventQueryRebond,
- EventQueryDupeout,
- EventQueryFork,
+var queries = []tmpubsub.Query{
EventQueryNewBlock,
EventQueryNewBlockHeader,
EventQueryNewRound,
@@ -167,5 +216,5 @@ var queries = []tmpubsub.Query{EventQueryBond,
EventQueryVote}
func randQuery() tmpubsub.Query {
- return queries[rand.Intn(len(queries))]
+ return queries[cmn.RandIntn(len(queries))]
}
diff --git a/types/events.go b/types/events.go
index 2b87297c..891c6a90 100644
--- a/types/events.go
+++ b/types/events.go
@@ -10,22 +10,17 @@ import (
// Reserved event types
const (
- EventBond = "Bond"
EventCompleteProposal = "CompleteProposal"
- EventDupeout = "Dupeout"
- EventFork = "Fork"
EventLock = "Lock"
EventNewBlock = "NewBlock"
EventNewBlockHeader = "NewBlockHeader"
EventNewRound = "NewRound"
EventNewRoundStep = "NewRoundStep"
EventPolka = "Polka"
- EventRebond = "Rebond"
EventRelock = "Relock"
EventTimeoutPropose = "TimeoutPropose"
EventTimeoutWait = "TimeoutWait"
EventTx = "Tx"
- EventUnbond = "Unbond"
EventUnlock = "Unlock"
EventVote = "Vote"
EventProposalHeartbeat = "ProposalHeartbeat"
@@ -113,11 +108,6 @@ const (
)
var (
- EventQueryBond = QueryForEvent(EventBond)
- EventQueryUnbond = QueryForEvent(EventUnbond)
- EventQueryRebond = QueryForEvent(EventRebond)
- EventQueryDupeout = QueryForEvent(EventDupeout)
- EventQueryFork = QueryForEvent(EventFork)
EventQueryNewBlock = QueryForEvent(EventNewBlock)
EventQueryNewBlockHeader = QueryForEvent(EventNewBlockHeader)
EventQueryNewRound = QueryForEvent(EventNewRound)
diff --git a/types/events_test.go b/types/events_test.go
new file mode 100644
index 00000000..a4b71d92
--- /dev/null
+++ b/types/events_test.go
@@ -0,0 +1,23 @@
+package types
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestQueryTxFor(t *testing.T) {
+ tx := Tx("foo")
+ assert.Equal(t,
+ fmt.Sprintf("tm.event='Tx' AND tx.hash='%X'", tx.Hash()),
+ EventQueryTxFor(tx).String(),
+ )
+}
+
+func TestQueryForEvent(t *testing.T) {
+ assert.Equal(t,
+ "tm.event='NewBlock'",
+ QueryForEvent(EventNewBlock).String(),
+ )
+}
diff --git a/types/evidence.go b/types/evidence.go
index 266375ec..6313f43a 100644
--- a/types/evidence.go
+++ b/types/evidence.go
@@ -4,7 +4,7 @@ import (
"bytes"
"fmt"
- "github.com/tendermint/go-amino"
+ amino "github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/merkle"
diff --git a/types/evidence_test.go b/types/evidence_test.go
index 5bbb2a37..54eba01c 100644
--- a/types/evidence_test.go
+++ b/types/evidence_test.go
@@ -36,7 +36,7 @@ func TestEvidence(t *testing.T) {
blockID3 := makeBlockID("blockhash", 10000, "partshash")
blockID4 := makeBlockID("blockhash", 10000, "partshash2")
- chainID := "mychain"
+ const chainID = "mychain"
vote1 := makeVote(val, chainID, 0, 10, 2, 1, blockID)
badVote := makeVote(val, chainID, 0, 10, 2, 1, blockID)
@@ -72,3 +72,30 @@ func TestEvidence(t *testing.T) {
}
}
}
+
+func TestDuplicatedVoteEvidence(t *testing.T) {
+ ev := randomDuplicatedVoteEvidence()
+
+ assert.True(t, ev.Equal(ev))
+ assert.False(t, ev.Equal(&DuplicateVoteEvidence{}))
+}
+
+func TestEvidenceList(t *testing.T) {
+ ev := randomDuplicatedVoteEvidence()
+ evl := EvidenceList([]Evidence{ev})
+
+ assert.NotNil(t, evl.Hash())
+ assert.True(t, evl.Has(ev))
+ assert.False(t, evl.Has(&DuplicateVoteEvidence{}))
+}
+
+func randomDuplicatedVoteEvidence() *DuplicateVoteEvidence {
+ val := NewMockPV()
+ blockID := makeBlockID("blockhash", 1000, "partshash")
+ blockID2 := makeBlockID("blockhash2", 1000, "partshash")
+ const chainID = "mychain"
+ return &DuplicateVoteEvidence{
+ VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID),
+ VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2),
+ }
+}
diff --git a/types/genesis.go b/types/genesis.go
index 0367c6b2..220ee0e0 100644
--- a/types/genesis.go
+++ b/types/genesis.go
@@ -26,17 +26,7 @@ type GenesisDoc struct {
ConsensusParams *ConsensusParams `json:"consensus_params,omitempty"`
Validators []GenesisValidator `json:"validators"`
AppHash cmn.HexBytes `json:"app_hash"`
- AppStateJSON json.RawMessage `json:"app_state,omitempty"`
- AppOptions json.RawMessage `json:"app_options,omitempty"` // DEPRECATED
-}
-
-// AppState returns raw application state.
-// TODO: replace with AppState field during next breaking release (0.18)
-func (genDoc *GenesisDoc) AppState() json.RawMessage {
- if len(genDoc.AppOptions) > 0 {
- return genDoc.AppOptions
- }
- return genDoc.AppStateJSON
+ AppState json.RawMessage `json:"app_state,omitempty"`
}
// SaveAs is a utility method for saving GenensisDoc as a JSON file.
diff --git a/types/genesis_test.go b/types/genesis_test.go
index 24398a9a..106e15fb 100644
--- a/types/genesis_test.go
+++ b/types/genesis_test.go
@@ -1,10 +1,14 @@
package types
import (
+ "io/ioutil"
+ "os"
"testing"
+ "time"
"github.com/stretchr/testify/assert"
- "github.com/tendermint/tendermint/crypto"
+ "github.com/stretchr/testify/require"
+ "github.com/tendermint/tendermint/crypto/ed25519"
)
func TestGenesisBad(t *testing.T) {
@@ -36,7 +40,7 @@ func TestGenesisGood(t *testing.T) {
// create a base gendoc from struct
baseGenDoc := &GenesisDoc{
ChainID: "abc",
- Validators: []GenesisValidator{{crypto.GenPrivKeyEd25519().PubKey(), 10, "myval"}},
+ Validators: []GenesisValidator{{ed25519.GenPrivKeyEd25519().PubKey(), 10, "myval"}},
}
genDocBytes, err = cdc.MarshalJSON(baseGenDoc)
assert.NoError(t, err, "error marshalling genDoc")
@@ -59,3 +63,44 @@ func TestGenesisGood(t *testing.T) {
genDoc, err = GenesisDocFromJSON(genDocBytes)
assert.Error(t, err, "expected error for genDoc json with block size of 0")
}
+
+func TestGenesisSaveAs(t *testing.T) {
+ tmpfile, err := ioutil.TempFile("", "genesis")
+ require.NoError(t, err)
+ defer os.Remove(tmpfile.Name())
+
+ genDoc := randomGenesisDoc()
+
+ // save
+ genDoc.SaveAs(tmpfile.Name())
+ stat, err := tmpfile.Stat()
+ require.NoError(t, err)
+ if err != nil && stat.Size() <= 0 {
+ t.Fatalf("SaveAs failed to write any bytes to %v", tmpfile.Name())
+ }
+
+ err = tmpfile.Close()
+ require.NoError(t, err)
+
+ // load
+ genDoc2, err := GenesisDocFromFile(tmpfile.Name())
+ require.NoError(t, err)
+
+ // fails to unknown reason
+ // assert.EqualValues(t, genDoc2, genDoc)
+ assert.Equal(t, genDoc2.Validators, genDoc.Validators)
+}
+
+func TestGenesisValidatorHash(t *testing.T) {
+ genDoc := randomGenesisDoc()
+ assert.NotEmpty(t, genDoc.ValidatorHash())
+}
+
+func randomGenesisDoc() *GenesisDoc {
+ return &GenesisDoc{
+ GenesisTime: time.Now().UTC(),
+ ChainID: "abc",
+ Validators: []GenesisValidator{{ed25519.GenPrivKeyEd25519().PubKey(), 10, "myval"}},
+ ConsensusParams: DefaultConsensusParams(),
+ }
+}
diff --git a/types/heartbeat_test.go b/types/heartbeat_test.go
index 174c3ba9..f55c0bf3 100644
--- a/types/heartbeat_test.go
+++ b/types/heartbeat_test.go
@@ -4,8 +4,7 @@ import (
"testing"
"github.com/stretchr/testify/require"
-
- "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
)
func TestHeartbeatCopy(t *testing.T) {
@@ -27,7 +26,7 @@ func TestHeartbeatString(t *testing.T) {
hb := &Heartbeat{ValidatorIndex: 1, Height: 11, Round: 2}
require.Equal(t, hb.String(), "Heartbeat{1:000000000000 11/02 (0) }")
- var key crypto.PrivKeyEd25519
+ var key ed25519.PrivKeyEd25519
sig, err := key.Sign([]byte("Tendermint"))
require.NoError(t, err)
hb.Signature = sig
diff --git a/types/params_test.go b/types/params_test.go
index f645585e..e8e13dba 100644
--- a/types/params_test.go
+++ b/types/params_test.go
@@ -6,6 +6,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ abci "github.com/tendermint/tendermint/abci/types"
)
func newConsensusParams(blockSize, partSize int) ConsensusParams {
@@ -86,3 +87,59 @@ func TestConsensusParamsHash(t *testing.T) {
assert.NotEqual(t, hashes[i], hashes[i+1])
}
}
+
+func TestConsensusParamsUpdate(t *testing.T) {
+ testCases := []struct {
+ params ConsensusParams
+ updates *abci.ConsensusParams
+ updatedParams ConsensusParams
+ }{
+ // empty updates
+ {
+ makeParams(1, 2, 3, 4, 5, 6),
+ &abci.ConsensusParams{},
+ makeParams(1, 2, 3, 4, 5, 6),
+ },
+ // negative BlockPartSizeBytes
+ {
+ makeParams(1, 2, 3, 4, 5, 6),
+ &abci.ConsensusParams{
+ BlockSize: &abci.BlockSize{
+ MaxBytes: -100,
+ MaxTxs: -200,
+ MaxGas: -300,
+ },
+ TxSize: &abci.TxSize{
+ MaxBytes: -400,
+ MaxGas: -500,
+ },
+ BlockGossip: &abci.BlockGossip{
+ BlockPartSizeBytes: -600,
+ },
+ },
+ makeParams(1, 2, 3, 4, 5, 6),
+ },
+ // fine updates
+ {
+ makeParams(1, 2, 3, 4, 5, 6),
+ &abci.ConsensusParams{
+ BlockSize: &abci.BlockSize{
+ MaxBytes: 100,
+ MaxTxs: 200,
+ MaxGas: 300,
+ },
+ TxSize: &abci.TxSize{
+ MaxBytes: 400,
+ MaxGas: 500,
+ },
+ BlockGossip: &abci.BlockGossip{
+ BlockPartSizeBytes: 600,
+ },
+ },
+ makeParams(100, 200, 300, 400, 500, 600),
+ },
+ }
+ for _, tc := range testCases {
+ assert.Equal(t, tc.updatedParams, tc.params.Update(tc.updates))
+ }
+}
diff --git a/types/part_set_test.go b/types/part_set_test.go
index 01437f05..3576e747 100644
--- a/types/part_set_test.go
+++ b/types/part_set_test.go
@@ -1,10 +1,12 @@
package types
import (
- "bytes"
"io/ioutil"
"testing"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
cmn "github.com/tendermint/tendermint/libs/common"
)
@@ -13,24 +15,21 @@ const (
)
func TestBasicPartSet(t *testing.T) {
-
// Construct random data of size partSize * 100
data := cmn.RandBytes(testPartSize * 100)
-
partSet := NewPartSetFromData(data, testPartSize)
- if len(partSet.Hash()) == 0 {
- t.Error("Expected to get hash")
- }
- if partSet.Total() != 100 {
- t.Errorf("Expected to get 100 parts, but got %v", partSet.Total())
- }
- if !partSet.IsComplete() {
- t.Errorf("PartSet should be complete")
- }
+
+ assert.NotEmpty(t, partSet.Hash())
+ assert.Equal(t, 100, partSet.Total())
+ assert.Equal(t, 100, partSet.BitArray().Size())
+ assert.True(t, partSet.HashesTo(partSet.Hash()))
+ assert.True(t, partSet.IsComplete())
+ assert.Equal(t, 100, partSet.Count())
// Test adding parts to a new partSet.
partSet2 := NewPartSetFromHeader(partSet.Header())
+ assert.True(t, partSet2.HasHeader(partSet.Header()))
for i := 0; i < partSet.Total(); i++ {
part := partSet.GetPart(i)
//t.Logf("\n%v", part)
@@ -39,31 +38,28 @@ func TestBasicPartSet(t *testing.T) {
t.Errorf("Failed to add part %v, error: %v", i, err)
}
}
+ // adding part with invalid index
+ added, err := partSet2.AddPart(&Part{Index: 10000})
+ assert.False(t, added)
+ assert.Error(t, err)
+ // adding existing part
+ added, err = partSet2.AddPart(partSet2.GetPart(0))
+ assert.False(t, added)
+ assert.Nil(t, err)
- if !bytes.Equal(partSet.Hash(), partSet2.Hash()) {
- t.Error("Expected to get same hash")
- }
- if partSet2.Total() != 100 {
- t.Errorf("Expected to get 100 parts, but got %v", partSet2.Total())
- }
- if !partSet2.IsComplete() {
- t.Errorf("Reconstructed PartSet should be complete")
- }
+ assert.Equal(t, partSet.Hash(), partSet2.Hash())
+ assert.Equal(t, 100, partSet2.Total())
+ assert.True(t, partSet2.IsComplete())
// Reconstruct data, assert that they are equal.
data2Reader := partSet2.GetReader()
data2, err := ioutil.ReadAll(data2Reader)
- if err != nil {
- t.Errorf("Error reading data2Reader: %v", err)
- }
- if !bytes.Equal(data, data2) {
- t.Errorf("Got wrong data.")
- }
+ require.NoError(t, err)
+ assert.Equal(t, data, data2)
}
func TestWrongProof(t *testing.T) {
-
// Construct random data of size partSize * 100
data := cmn.RandBytes(testPartSize * 100)
partSet := NewPartSetFromData(data, testPartSize)
@@ -86,5 +82,4 @@ func TestWrongProof(t *testing.T) {
if added || err == nil {
t.Errorf("Expected to fail adding a part with bad bytes.")
}
-
}
diff --git a/types/priv_validator.go b/types/priv_validator.go
index 85db65a4..93225562 100644
--- a/types/priv_validator.go
+++ b/types/priv_validator.go
@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
)
// PrivValidator defines the functionality of a local Tendermint validator
@@ -47,7 +48,7 @@ type MockPV struct {
}
func NewMockPV() *MockPV {
- return &MockPV{crypto.GenPrivKeyEd25519()}
+ return &MockPV{ed25519.GenPrivKeyEd25519()}
}
// Implements PrivValidator.
diff --git a/types/protobuf.go b/types/protobuf.go
index ad7362e0..0e1e446d 100644
--- a/types/protobuf.go
+++ b/types/protobuf.go
@@ -7,7 +7,9 @@ import (
"time"
abci "github.com/tendermint/tendermint/abci/types"
- crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
+ "github.com/tendermint/tendermint/crypto/secp256k1"
)
//-------------------------------------------------------
@@ -61,12 +63,12 @@ func (tm2pb) Validator(val *Validator) abci.Validator {
// TODO: add cases when new pubkey types are added to crypto
func (tm2pb) PubKey(pubKey crypto.PubKey) abci.PubKey {
switch pk := pubKey.(type) {
- case crypto.PubKeyEd25519:
+ case ed25519.PubKeyEd25519:
return abci.PubKey{
Type: ABCIPubKeyTypeEd25519,
Data: pk[:],
}
- case crypto.PubKeySecp256k1:
+ case secp256k1.PubKeySecp256k1:
return abci.PubKey{
Type: ABCIPubKeyTypeSecp256k1,
Data: pk[:],
@@ -78,7 +80,7 @@ func (tm2pb) PubKey(pubKey crypto.PubKey) abci.PubKey {
// XXX: panics on nil or unknown pubkey type
func (tm2pb) Validators(vals *ValidatorSet) []abci.Validator {
- validators := make([]abci.Validator, len(vals.Validators))
+ validators := make([]abci.Validator, vals.Size())
for i, val := range vals.Validators {
validators[i] = TM2PB.Validator(val)
}
@@ -161,14 +163,14 @@ func (pb2tm) PubKey(pubKey abci.PubKey) (crypto.PubKey, error) {
if len(pubKey.Data) != sizeEd {
return nil, fmt.Errorf("Invalid size for PubKeyEd25519. Got %d, expected %d", len(pubKey.Data), sizeEd)
}
- var pk crypto.PubKeyEd25519
+ var pk ed25519.PubKeyEd25519
copy(pk[:], pubKey.Data)
return pk, nil
case ABCIPubKeyTypeSecp256k1:
if len(pubKey.Data) != sizeSecp {
return nil, fmt.Errorf("Invalid size for PubKeyEd25519. Got %d, expected %d", len(pubKey.Data), sizeSecp)
}
- var pk crypto.PubKeySecp256k1
+ var pk secp256k1.PubKeySecp256k1
copy(pk[:], pubKey.Data)
return pk, nil
default:
diff --git a/types/protobuf_test.go b/types/protobuf_test.go
index cd986fd8..add9b332 100644
--- a/types/protobuf_test.go
+++ b/types/protobuf_test.go
@@ -2,15 +2,18 @@ package types
import (
"testing"
+ "time"
"github.com/stretchr/testify/assert"
abci "github.com/tendermint/tendermint/abci/types"
crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
+ "github.com/tendermint/tendermint/crypto/secp256k1"
)
func TestABCIPubKey(t *testing.T) {
- pkEd := crypto.GenPrivKeyEd25519().PubKey()
- pkSecp := crypto.GenPrivKeySecp256k1().PubKey()
+ pkEd := ed25519.GenPrivKeyEd25519().PubKey()
+ pkSecp := secp256k1.GenPrivKeySecp256k1().PubKey()
testABCIPubKey(t, pkEd, ABCIPubKeyTypeEd25519)
testABCIPubKey(t, pkSecp, ABCIPubKeyTypeSecp256k1)
}
@@ -23,7 +26,7 @@ func testABCIPubKey(t *testing.T, pk crypto.PubKey, typeStr string) {
}
func TestABCIValidators(t *testing.T) {
- pkEd := crypto.GenPrivKeyEd25519().PubKey()
+ pkEd := ed25519.GenPrivKeyEd25519().PubKey()
// correct validator
tmValExpected := &Validator{
@@ -43,6 +46,9 @@ func TestABCIValidators(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, tmValExpected, tmVals[0])
+ abciVals := TM2PB.Validators(NewValidatorSet(tmVals))
+ assert.Equal(t, []abci.Validator{abciVal}, abciVals)
+
// val with address
tmVal.Address = pkEd.Address()
@@ -67,3 +73,50 @@ func TestABCIConsensusParams(t *testing.T) {
assert.Equal(t, *cp, cp2)
}
+
+func TestABCIHeader(t *testing.T) {
+ header := &Header{
+ Height: int64(3),
+ Time: time.Now(),
+ NumTxs: int64(10),
+ }
+ abciHeader := TM2PB.Header(header)
+
+ assert.Equal(t, int64(3), abciHeader.Height)
+}
+
+func TestABCIEvidence(t *testing.T) {
+ val := NewMockPV()
+ blockID := makeBlockID("blockhash", 1000, "partshash")
+ blockID2 := makeBlockID("blockhash2", 1000, "partshash")
+ const chainID = "mychain"
+ ev := &DuplicateVoteEvidence{
+ PubKey: val.GetPubKey(),
+ VoteA: makeVote(val, chainID, 0, 10, 2, 1, blockID),
+ VoteB: makeVote(val, chainID, 0, 10, 2, 1, blockID2),
+ }
+ abciEv := TM2PB.Evidence(
+ ev,
+ NewValidatorSet([]*Validator{NewValidator(val.GetPubKey(), 10)}),
+ time.Now(),
+ )
+
+ assert.Equal(t, "duplicate/vote", abciEv.Type)
+}
+
+type pubKeyEddie struct{}
+
+func (pubKeyEddie) Address() Address { return []byte{} }
+func (pubKeyEddie) Bytes() []byte { return []byte{} }
+func (pubKeyEddie) VerifyBytes(msg []byte, sig crypto.Signature) bool { return false }
+func (pubKeyEddie) Equals(crypto.PubKey) bool { return false }
+
+func TestABCIValidatorFromPubKeyAndPower(t *testing.T) {
+ pubkey := ed25519.GenPrivKeyEd25519().PubKey()
+
+ abciVal := TM2PB.ValidatorFromPubKeyAndPower(pubkey, 10)
+ assert.Equal(t, int64(10), abciVal.Power)
+
+ assert.Panics(t, func() { TM2PB.ValidatorFromPubKeyAndPower(nil, 10) })
+ assert.Panics(t, func() { TM2PB.ValidatorFromPubKeyAndPower(pubKeyEddie{}, 10) })
+}
diff --git a/types/results.go b/types/results.go
index 7f8e6093..17d5891c 100644
--- a/types/results.go
+++ b/types/results.go
@@ -24,15 +24,16 @@ func (a ABCIResult) Hash() []byte {
// ABCIResults wraps the deliver tx results to return a proof
type ABCIResults []ABCIResult
-// NewResults creates ABCIResults from ResponseDeliverTx
-func NewResults(del []*abci.ResponseDeliverTx) ABCIResults {
- res := make(ABCIResults, len(del))
- for i, d := range del {
+// NewResults creates ABCIResults from the list of ResponseDeliverTx.
+func NewResults(responses []*abci.ResponseDeliverTx) ABCIResults {
+ res := make(ABCIResults, len(responses))
+ for i, d := range responses {
res[i] = NewResultFromResponse(d)
}
return res
}
+// NewResultFromResponse creates ABCIResult from ResponseDeliverTx.
func NewResultFromResponse(response *abci.ResponseDeliverTx) ABCIResult {
return ABCIResult{
Code: response.Code,
diff --git a/types/results_test.go b/types/results_test.go
index 009e2693..8cbe319f 100644
--- a/types/results_test.go
+++ b/types/results_test.go
@@ -5,6 +5,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ abci "github.com/tendermint/tendermint/abci/types"
)
func TestABCIResults(t *testing.T) {
@@ -41,3 +42,14 @@ func TestABCIResults(t *testing.T) {
assert.True(t, valid, "%d", i)
}
}
+
+func TestABCIBytes(t *testing.T) {
+ results := NewResults([]*abci.ResponseDeliverTx{
+ {Code: 0, Data: []byte{}},
+ {Code: 0, Data: []byte("one")},
+ {Code: 14, Data: nil},
+ {Code: 14, Data: []byte("foo")},
+ {Code: 14, Data: []byte("bar")},
+ })
+ assert.NotNil(t, results.Bytes())
+}
diff --git a/types/tx_test.go b/types/tx_test.go
index 67df5c5f..df7a7449 100644
--- a/types/tx_test.go
+++ b/types/tx_test.go
@@ -24,21 +24,32 @@ func randInt(low, high int) int {
}
func TestTxIndex(t *testing.T) {
- assert := assert.New(t)
for i := 0; i < 20; i++ {
txs := makeTxs(15, 60)
for j := 0; j < len(txs); j++ {
tx := txs[j]
idx := txs.Index(tx)
- assert.Equal(j, idx)
+ assert.Equal(t, j, idx)
}
- assert.Equal(-1, txs.Index(nil))
- assert.Equal(-1, txs.Index(Tx("foodnwkf")))
+ assert.Equal(t, -1, txs.Index(nil))
+ assert.Equal(t, -1, txs.Index(Tx("foodnwkf")))
+ }
+}
+
+func TestTxIndexByHash(t *testing.T) {
+ for i := 0; i < 20; i++ {
+ txs := makeTxs(15, 60)
+ for j := 0; j < len(txs); j++ {
+ tx := txs[j]
+ idx := txs.IndexByHash(tx.Hash())
+ assert.Equal(t, j, idx)
+ }
+ assert.Equal(t, -1, txs.IndexByHash(nil))
+ assert.Equal(t, -1, txs.IndexByHash(Tx("foodnwkf").Hash()))
}
}
func TestValidTxProof(t *testing.T) {
- assert := assert.New(t)
cases := []struct {
txs Txs
}{
@@ -58,21 +69,21 @@ func TestValidTxProof(t *testing.T) {
leaf := txs[i]
leafHash := leaf.Hash()
proof := txs.Proof(i)
- assert.Equal(i, proof.Index, "%d: %d", h, i)
- assert.Equal(len(txs), proof.Total, "%d: %d", h, i)
- assert.EqualValues(root, proof.RootHash, "%d: %d", h, i)
- assert.EqualValues(leaf, proof.Data, "%d: %d", h, i)
- assert.EqualValues(leafHash, proof.LeafHash(), "%d: %d", h, i)
- assert.Nil(proof.Validate(root), "%d: %d", h, i)
- assert.NotNil(proof.Validate([]byte("foobar")), "%d: %d", h, i)
+ assert.Equal(t, i, proof.Index, "%d: %d", h, i)
+ assert.Equal(t, len(txs), proof.Total, "%d: %d", h, i)
+ assert.EqualValues(t, root, proof.RootHash, "%d: %d", h, i)
+ assert.EqualValues(t, leaf, proof.Data, "%d: %d", h, i)
+ assert.EqualValues(t, leafHash, proof.LeafHash(), "%d: %d", h, i)
+ assert.Nil(t, proof.Validate(root), "%d: %d", h, i)
+ assert.NotNil(t, proof.Validate([]byte("foobar")), "%d: %d", h, i)
// read-write must also work
var p2 TxProof
bin, err := cdc.MarshalBinary(proof)
- assert.Nil(err)
+ assert.Nil(t, err)
err = cdc.UnmarshalBinary(bin, &p2)
- if assert.Nil(err, "%d: %d: %+v", h, i, err) {
- assert.Nil(p2.Validate(root), "%d: %d", h, i)
+ if assert.Nil(t, err, "%d: %d: %+v", h, i, err) {
+ assert.Nil(t, p2.Validate(root), "%d: %d", h, i)
}
}
}
@@ -86,8 +97,6 @@ func TestTxProofUnchangable(t *testing.T) {
}
func testTxProofUnchangable(t *testing.T) {
- assert := assert.New(t)
-
// make some proof
txs := makeTxs(randInt(2, 100), randInt(16, 128))
root := txs.Hash()
@@ -95,9 +104,9 @@ func testTxProofUnchangable(t *testing.T) {
proof := txs.Proof(i)
// make sure it is valid to start with
- assert.Nil(proof.Validate(root))
+ assert.Nil(t, proof.Validate(root))
bin, err := cdc.MarshalBinary(proof)
- assert.Nil(err)
+ assert.Nil(t, err)
// try mutating the data and make sure nothing breaks
for j := 0; j < 500; j++ {
diff --git a/types/validator_set.go b/types/validator_set.go
index 191f8b42..60fc2d83 100644
--- a/types/validator_set.go
+++ b/types/validator_set.go
@@ -39,14 +39,15 @@ func NewValidatorSet(vals []*Validator) *ValidatorSet {
Validators: validators,
}
- if vals != nil {
+ if len(vals) > 0 {
vs.IncrementAccum(1)
}
return vs
}
-// incrementAccum and update the proposer
+// IncrementAccum increments accum of each validator and updates the
+// proposer. Panics if validator set is empty.
func (valSet *ValidatorSet) IncrementAccum(times int) {
// Add VotingPower * times to each validator and order into heap.
validatorsHeap := cmn.NewHeap()
diff --git a/types/validator_set_test.go b/types/validator_set_test.go
index 61f4dada..c8566677 100644
--- a/types/validator_set_test.go
+++ b/types/validator_set_test.go
@@ -11,9 +11,64 @@ import (
"github.com/stretchr/testify/assert"
crypto "github.com/tendermint/tendermint/crypto"
+ "github.com/tendermint/tendermint/crypto/ed25519"
cmn "github.com/tendermint/tendermint/libs/common"
)
+func TestValidatorSetBasic(t *testing.T) {
+ for _, vset := range []*ValidatorSet{NewValidatorSet([]*Validator{}), NewValidatorSet(nil)} {
+ assert.Panics(t, func() { vset.IncrementAccum(1) })
+
+ assert.EqualValues(t, vset, vset.Copy())
+ assert.False(t, vset.HasAddress([]byte("some val")))
+ idx, val := vset.GetByAddress([]byte("some val"))
+ assert.Equal(t, -1, idx)
+ assert.Nil(t, val)
+ addr, val := vset.GetByIndex(-100)
+ assert.Nil(t, addr)
+ assert.Nil(t, val)
+ addr, val = vset.GetByIndex(0)
+ assert.Nil(t, addr)
+ assert.Nil(t, val)
+ addr, val = vset.GetByIndex(100)
+ assert.Nil(t, addr)
+ assert.Nil(t, val)
+ assert.Zero(t, vset.Size())
+ assert.Equal(t, int64(0), vset.TotalVotingPower())
+ assert.Nil(t, vset.GetProposer())
+ assert.Nil(t, vset.Hash())
+
+ // add
+ val = randValidator_()
+ assert.True(t, vset.Add(val))
+ assert.True(t, vset.HasAddress(val.Address))
+ idx, val2 := vset.GetByAddress(val.Address)
+ assert.Equal(t, 0, idx)
+ assert.Equal(t, val, val2)
+ addr, val2 = vset.GetByIndex(0)
+ assert.Equal(t, []byte(val.Address), addr)
+ assert.Equal(t, val, val2)
+ assert.Equal(t, 1, vset.Size())
+ assert.Equal(t, val.VotingPower, vset.TotalVotingPower())
+ assert.Equal(t, val, vset.GetProposer())
+ assert.NotNil(t, vset.Hash())
+ assert.NotPanics(t, func() { vset.IncrementAccum(1) })
+
+ // update
+ assert.False(t, vset.Update(randValidator_()))
+ val.VotingPower = 100
+ assert.True(t, vset.Update(val))
+
+ // remove
+ val2, removed := vset.Remove(randValidator_().Address)
+ assert.Nil(t, val2)
+ assert.False(t, removed)
+ val2, removed = vset.Remove(val.Address)
+ assert.Equal(t, val.Address, val2.Address)
+ assert.True(t, removed)
+ }
+}
+
func TestCopy(t *testing.T) {
vset := randValidatorSet(10)
vsetHash := vset.Hash()
@@ -33,7 +88,7 @@ func BenchmarkValidatorSetCopy(b *testing.B) {
b.StopTimer()
vset := NewValidatorSet([]*Validator{})
for i := 0; i < 1000; i++ {
- privKey := crypto.GenPrivKeyEd25519()
+ privKey := ed25519.GenPrivKeyEd25519()
pubKey := privKey.PubKey()
val := NewValidator(pubKey, 0)
if !vset.Add(val) {
@@ -197,7 +252,7 @@ func newValidator(address []byte, power int64) *Validator {
func randPubKey() crypto.PubKey {
var pubKey [32]byte
copy(pubKey[:], cmn.RandBytes(32))
- return crypto.PubKeyEd25519(pubKey)
+ return ed25519.PubKeyEd25519(pubKey)
}
func randValidator_() *Validator {
@@ -314,7 +369,7 @@ func TestSafeSubClip(t *testing.T) {
//-------------------------------------------------------------------
func TestValidatorSetVerifyCommit(t *testing.T) {
- privKey := crypto.GenPrivKeyEd25519()
+ privKey := ed25519.GenPrivKeyEd25519()
pubKey := privKey.PubKey()
v1 := NewValidator(pubKey, 1000)
vset := NewValidatorSet([]*Validator{v1})
diff --git a/types/vote_test.go b/types/vote_test.go
index cbb22aaa..5de451d4 100644
--- a/types/vote_test.go
+++ b/types/vote_test.go
@@ -4,7 +4,9 @@ import (
"testing"
"time"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/tendermint/tendermint/crypto/ed25519"
)
func examplePrevote() *Vote {
@@ -50,29 +52,9 @@ func TestVoteSignable(t *testing.T) {
}
}
-func TestVoteString(t *testing.T) {
- tc := []struct {
- name string
- in string
- out string
- }{
- {"Precommit", examplePrecommit().String(), `Vote{56789:616464720000 12345/02/2(Precommit) 686173680000 @ 2017-12-25T03:00:01.234Z}`},
- {"Prevote", examplePrevote().String(), `Vote{56789:616464720000 12345/02/1(Prevote) 686173680000 @ 2017-12-25T03:00:01.234Z}`},
- }
-
- for _, tt := range tc {
- tt := tt
- t.Run(tt.name, func(st *testing.T) {
- if tt.in != tt.out {
- t.Errorf("Got unexpected string for Proposal. Expected:\n%v\nGot:\n%v", tt.in, tt.out)
- }
- })
- }
-}
-
func TestVoteVerifySignature(t *testing.T) {
privVal := NewMockPV()
- pubKey := privVal.GetPubKey()
+ pubkey := privVal.GetPubKey()
vote := examplePrecommit()
signBytes := vote.SignBytes("test_chain_id")
@@ -82,7 +64,7 @@ func TestVoteVerifySignature(t *testing.T) {
require.NoError(t, err)
// verify the same vote
- valid := pubKey.VerifyBytes(vote.SignBytes("test_chain_id"), vote.Signature)
+ valid := pubkey.VerifyBytes(vote.SignBytes("test_chain_id"), vote.Signature)
require.True(t, valid)
// serialize, deserialize and verify again....
@@ -95,7 +77,7 @@ func TestVoteVerifySignature(t *testing.T) {
// verify the transmitted vote
newSignBytes := precommit.SignBytes("test_chain_id")
require.Equal(t, string(signBytes), string(newSignBytes))
- valid = pubKey.VerifyBytes(newSignBytes, precommit.Signature)
+ valid = pubkey.VerifyBytes(newSignBytes, precommit.Signature)
require.True(t, valid)
}
@@ -119,3 +101,21 @@ func TestIsVoteTypeValid(t *testing.T) {
})
}
}
+
+func TestVoteVerify(t *testing.T) {
+ privVal := NewMockPV()
+ pubkey := privVal.GetPubKey()
+
+ vote := examplePrevote()
+ vote.ValidatorAddress = pubkey.Address()
+
+ err := vote.Verify("test_chain_id", ed25519.GenPrivKeyEd25519().PubKey())
+ if assert.Error(t, err) {
+ assert.Equal(t, ErrVoteInvalidValidatorAddress, err)
+ }
+
+ err = vote.Verify("test_chain_id", pubkey)
+ if assert.Error(t, err) {
+ assert.Equal(t, ErrVoteInvalidSignature, err)
+ }
+}
diff --git a/types/wire.go b/types/wire.go
index 6342d7eb..9221de96 100644
--- a/types/wire.go
+++ b/types/wire.go
@@ -2,11 +2,11 @@ package types
import (
"github.com/tendermint/go-amino"
- "github.com/tendermint/tendermint/crypto"
+ cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
)
var cdc = amino.NewCodec()
func init() {
- crypto.RegisterAmino(cdc)
+ cryptoAmino.RegisterAmino(cdc)
}
diff --git a/version/version.go b/version/version.go
index f9faedf0..165f2582 100644
--- a/version/version.go
+++ b/version/version.go
@@ -4,13 +4,13 @@ package version
const (
Maj = "0"
Min = "22"
- Fix = "2"
+ Fix = "4"
)
var (
// Version is the current version of Tendermint
// Must be a string because scripts like dist.sh read this file.
- Version = "0.22.2-dev"
+ Version = "0.22.4"
// GitCommit is the current HEAD set using ldflags.
GitCommit string