mirror of
https://github.com/fluencelabs/tendermint
synced 2025-07-24 08:41:59 +00:00
Compare commits
3 Commits
2926_don_p
...
v0.27.4
Author | SHA1 | Date | |
---|---|---|---|
|
1e1ca15bcc | ||
|
c6604b5a9b | ||
|
c510f823e7 |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## v0.27.4
|
||||
|
||||
*December 21st, 2018*
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
- [mempool] [\#3036](https://github.com/tendermint/tendermint/issues/3036) Fix
|
||||
LRU cache by popping the least recently used item when the cache is full,
|
||||
not the most recently used one!
|
||||
|
||||
## v0.27.3
|
||||
|
||||
*December 16th, 2018*
|
||||
|
@@ -7,16 +7,10 @@ Special thanks to external contributors on this release:
|
||||
### BREAKING CHANGES:
|
||||
|
||||
* CLI/RPC/Config
|
||||
- [cli] Removed `node` `--proxy_app=dummy` option. Use `kvstore` (`persistent_kvstore`) instead.
|
||||
- [cli] Renamed `node` `--proxy_app=nilapp` to `--proxy_app=noop`.
|
||||
|
||||
- [privval] \#2926 split up `PubKeyMsg` into `PubKeyRequest` and `PubKeyResponse` to be consistent with other message types
|
||||
|
||||
* Apps
|
||||
|
||||
* Go API
|
||||
- [types] \#2926 memoize consensus public key on initialization of remote signer and return the memoized key on
|
||||
`PrivValidator.GetPubKey()` instead of requesting it again
|
||||
* Go API
|
||||
|
||||
* Blockchain Protocol
|
||||
|
||||
@@ -27,4 +21,4 @@ Special thanks to external contributors on this release:
|
||||
### IMPROVEMENTS:
|
||||
|
||||
### BUG FIXES:
|
||||
- [types] \#2926 do not panic if retrieving the private validator's public key fails
|
||||
|
||||
|
@@ -58,7 +58,7 @@ var RootCmd = &cobra.Command{
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
switch cmd.Use {
|
||||
case "counter", "kvstore": // for the examples apps, don't pre-run
|
||||
case "counter", "kvstore", "dummy": // for the examples apps, don't pre-run
|
||||
return nil
|
||||
case "version": // skip running for version command
|
||||
return nil
|
||||
@@ -127,6 +127,10 @@ func addCounterFlags() {
|
||||
counterCmd.PersistentFlags().BoolVarP(&flagSerial, "serial", "", false, "enforce incrementing (serial) transactions")
|
||||
}
|
||||
|
||||
func addDummyFlags() {
|
||||
dummyCmd.PersistentFlags().StringVarP(&flagPersist, "persist", "", "", "directory to use for a database")
|
||||
}
|
||||
|
||||
func addKVStoreFlags() {
|
||||
kvstoreCmd.PersistentFlags().StringVarP(&flagPersist, "persist", "", "", "directory to use for a database")
|
||||
}
|
||||
@@ -148,6 +152,10 @@ func addCommands() {
|
||||
// examples
|
||||
addCounterFlags()
|
||||
RootCmd.AddCommand(counterCmd)
|
||||
// deprecated, left for backwards compatibility
|
||||
addDummyFlags()
|
||||
RootCmd.AddCommand(dummyCmd)
|
||||
// replaces dummy, see issue #196
|
||||
addKVStoreFlags()
|
||||
RootCmd.AddCommand(kvstoreCmd)
|
||||
}
|
||||
@@ -283,6 +291,18 @@ var counterCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
// deprecated, left for backwards compatibility
|
||||
var dummyCmd = &cobra.Command{
|
||||
Use: "dummy",
|
||||
Deprecated: "use: [abci-cli kvstore] instead",
|
||||
Short: "ABCI demo example",
|
||||
Long: "ABCI demo example",
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return cmdKVStore(cmd, args)
|
||||
},
|
||||
}
|
||||
|
||||
var kvstoreCmd = &cobra.Command{
|
||||
Use: "kvstore",
|
||||
Short: "ABCI demo example",
|
||||
|
@@ -24,7 +24,7 @@ func AddNodeFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing")
|
||||
|
||||
// abci flags
|
||||
cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or one of: 'kvstore', 'persistent_kvstore', 'counter', 'counter_serial' or 'noop' for local testing.")
|
||||
cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'kvstore' for local testing.")
|
||||
cmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)")
|
||||
|
||||
// rpc flags
|
||||
|
@@ -16,8 +16,6 @@ var ShowValidatorCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func showValidator(cmd *cobra.Command, args []string) {
|
||||
// TODO(ismail): add a flag and check if we actually want to see the pub key
|
||||
// of the remote signer instead of the FilePV
|
||||
privValidator := privval.LoadOrGenFilePV(config.PrivValidatorFile())
|
||||
pubKeyJSONBytes, _ := cdc.MarshalJSON(privValidator.GetPubKey())
|
||||
fmt.Println(string(pubKeyJSONBytes))
|
||||
|
@@ -659,6 +659,12 @@ func TestInitChainUpdateValidators(t *testing.T) {
|
||||
assert.Equal(t, newValAddr, expectValAddr)
|
||||
}
|
||||
|
||||
func newInitChainApp(vals []abci.ValidatorUpdate) *initChainApp {
|
||||
return &initChainApp{
|
||||
vals: vals,
|
||||
}
|
||||
}
|
||||
|
||||
// returns the vals on InitChain
|
||||
type initChainApp struct {
|
||||
abci.BaseApplication
|
||||
|
@@ -2,14 +2,13 @@ package consensus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
"github.com/tendermint/tendermint/libs/fail"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
@@ -113,7 +113,7 @@ blocks are produced regularly, even if there are no transactions. See
|
||||
_No Empty Blocks_, below, to modify this setting.
|
||||
|
||||
Tendermint supports in-process versions of the `counter`, `kvstore` and
|
||||
`noop` apps that ship as examples with `abci-cli`. It's easy to compile
|
||||
`nil` apps that ship as examples with `abci-cli`. It's easy to compile
|
||||
your own app in-process with Tendermint if it's written in Go. If your
|
||||
app is not written in Go, simply run it in another process, and use the
|
||||
`--proxy_app` flag to specify the address of the socket it is listening
|
||||
|
@@ -676,7 +676,7 @@ func (cache *mapTxCache) Push(tx types.Tx) bool {
|
||||
// Use the tx hash in the cache
|
||||
txHash := sha256.Sum256(tx)
|
||||
if moved, exists := cache.map_[txHash]; exists {
|
||||
cache.list.MoveToFront(moved)
|
||||
cache.list.MoveToBack(moved)
|
||||
return false
|
||||
}
|
||||
|
||||
|
@@ -67,10 +67,7 @@ func (sc *IPCVal) OnStart() error {
|
||||
return err
|
||||
}
|
||||
|
||||
sc.RemoteSignerClient, err = NewRemoteSignerClient(sc.conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sc.RemoteSignerClient = NewRemoteSignerClient(sc.conn)
|
||||
|
||||
// Start a routine to keep the connection alive
|
||||
sc.cancelPing = make(chan struct{}, 1)
|
||||
|
@@ -6,8 +6,6 @@ import (
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
@@ -17,9 +15,8 @@ import (
|
||||
// RemoteSignerClient implements PrivValidator, it uses a socket to request signatures
|
||||
// from an external process.
|
||||
type RemoteSignerClient struct {
|
||||
conn net.Conn
|
||||
consensusPubKey crypto.PubKey
|
||||
mtx sync.Mutex
|
||||
conn net.Conn
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Check that RemoteSignerClient implements PrivValidator.
|
||||
@@ -28,34 +25,38 @@ var _ types.PrivValidator = (*RemoteSignerClient)(nil)
|
||||
// NewRemoteSignerClient returns an instance of RemoteSignerClient.
|
||||
func NewRemoteSignerClient(
|
||||
conn net.Conn,
|
||||
) (*RemoteSignerClient, error) {
|
||||
) *RemoteSignerClient {
|
||||
sc := &RemoteSignerClient{
|
||||
conn: conn,
|
||||
}
|
||||
pubKey, err := sc.getPubKey()
|
||||
if err != nil {
|
||||
return nil, cmn.ErrorWrap(err, "error while retrieving public key for remote signer")
|
||||
}
|
||||
// retrieve and memoize the consensus public key once:
|
||||
sc.consensusPubKey = pubKey
|
||||
return sc, nil
|
||||
}
|
||||
|
||||
// GetPubKey implements PrivValidator.
|
||||
func (sc *RemoteSignerClient) GetPubKey() crypto.PubKey {
|
||||
return sc.consensusPubKey
|
||||
return sc
|
||||
}
|
||||
|
||||
// GetAddress implements PrivValidator.
|
||||
func (sc *RemoteSignerClient) GetAddress() types.Address {
|
||||
return sc.consensusPubKey.Address()
|
||||
pubKey, err := sc.getPubKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return pubKey.Address()
|
||||
}
|
||||
|
||||
// GetPubKey implements PrivValidator.
|
||||
func (sc *RemoteSignerClient) GetPubKey() crypto.PubKey {
|
||||
pubKey, err := sc.getPubKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return pubKey
|
||||
}
|
||||
|
||||
func (sc *RemoteSignerClient) getPubKey() (crypto.PubKey, error) {
|
||||
sc.mtx.Lock()
|
||||
defer sc.mtx.Unlock()
|
||||
sc.lock.Lock()
|
||||
defer sc.lock.Unlock()
|
||||
|
||||
err := writeMsg(sc.conn, &PubKeyRequest{})
|
||||
err := writeMsg(sc.conn, &PubKeyMsg{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -64,22 +65,14 @@ func (sc *RemoteSignerClient) getPubKey() (crypto.PubKey, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pubKeyResp, ok := res.(*PubKeyResponse)
|
||||
if !ok {
|
||||
return nil, errors.Wrap(ErrUnexpectedResponse, "response is not PubKeyResponse")
|
||||
}
|
||||
|
||||
if pubKeyResp.Error != nil {
|
||||
return nil, errors.Wrap(pubKeyResp.Error, "failed to get private validator's public key")
|
||||
}
|
||||
|
||||
return pubKeyResp.PubKey, nil
|
||||
return res.(*PubKeyMsg).PubKey, nil
|
||||
}
|
||||
|
||||
// SignVote implements PrivValidator.
|
||||
func (sc *RemoteSignerClient) SignVote(chainID string, vote *types.Vote) error {
|
||||
sc.mtx.Lock()
|
||||
defer sc.mtx.Unlock()
|
||||
sc.lock.Lock()
|
||||
defer sc.lock.Unlock()
|
||||
|
||||
err := writeMsg(sc.conn, &SignVoteRequest{Vote: vote})
|
||||
if err != nil {
|
||||
@@ -108,8 +101,8 @@ func (sc *RemoteSignerClient) SignProposal(
|
||||
chainID string,
|
||||
proposal *types.Proposal,
|
||||
) error {
|
||||
sc.mtx.Lock()
|
||||
defer sc.mtx.Unlock()
|
||||
sc.lock.Lock()
|
||||
defer sc.lock.Unlock()
|
||||
|
||||
err := writeMsg(sc.conn, &SignProposalRequest{Proposal: proposal})
|
||||
if err != nil {
|
||||
@@ -134,8 +127,8 @@ func (sc *RemoteSignerClient) SignProposal(
|
||||
|
||||
// Ping is used to check connection health.
|
||||
func (sc *RemoteSignerClient) Ping() error {
|
||||
sc.mtx.Lock()
|
||||
defer sc.mtx.Unlock()
|
||||
sc.lock.Lock()
|
||||
defer sc.lock.Unlock()
|
||||
|
||||
err := writeMsg(sc.conn, &PingRequest{})
|
||||
if err != nil {
|
||||
@@ -159,8 +152,7 @@ type RemoteSignerMsg interface{}
|
||||
|
||||
func RegisterRemoteSignerMsg(cdc *amino.Codec) {
|
||||
cdc.RegisterInterface((*RemoteSignerMsg)(nil), nil)
|
||||
cdc.RegisterConcrete(&PubKeyRequest{}, "tendermint/remotesigner/PubKeyRequest", nil)
|
||||
cdc.RegisterConcrete(&PubKeyResponse{}, "tendermint/remotesigner/PubKeyResponse", nil)
|
||||
cdc.RegisterConcrete(&PubKeyMsg{}, "tendermint/remotesigner/PubKeyMsg", nil)
|
||||
cdc.RegisterConcrete(&SignVoteRequest{}, "tendermint/remotesigner/SignVoteRequest", nil)
|
||||
cdc.RegisterConcrete(&SignedVoteResponse{}, "tendermint/remotesigner/SignedVoteResponse", nil)
|
||||
cdc.RegisterConcrete(&SignProposalRequest{}, "tendermint/remotesigner/SignProposalRequest", nil)
|
||||
@@ -169,13 +161,9 @@ func RegisterRemoteSignerMsg(cdc *amino.Codec) {
|
||||
cdc.RegisterConcrete(&PingResponse{}, "tendermint/remotesigner/PingResponse", nil)
|
||||
}
|
||||
|
||||
// PubKeyRequest requests the consensus public key from the remote signer.
|
||||
type PubKeyRequest struct{}
|
||||
|
||||
// PubKeyResponse is a PrivValidatorSocket message containing the public key.
|
||||
type PubKeyResponse struct {
|
||||
// PubKeyMsg is a PrivValidatorSocket message containing the public key.
|
||||
type PubKeyMsg struct {
|
||||
PubKey crypto.PubKey
|
||||
Error *RemoteSignerError
|
||||
}
|
||||
|
||||
// SignVoteRequest is a PrivValidatorSocket message containing a vote.
|
||||
@@ -239,10 +227,10 @@ func handleRequest(req RemoteSignerMsg, chainID string, privVal types.PrivValida
|
||||
var err error
|
||||
|
||||
switch r := req.(type) {
|
||||
case *PubKeyRequest:
|
||||
case *PubKeyMsg:
|
||||
var p crypto.PubKey
|
||||
p = privVal.GetPubKey()
|
||||
res = &PubKeyResponse{p, nil}
|
||||
res = &PubKeyMsg{p}
|
||||
case *SignVoteRequest:
|
||||
err = privVal.SignVote(chainID, r.Vote)
|
||||
if err != nil {
|
||||
|
@@ -107,10 +107,8 @@ func (sc *TCPVal) OnStart() error {
|
||||
}
|
||||
|
||||
sc.conn = conn
|
||||
sc.RemoteSignerClient, err = NewRemoteSignerClient(sc.conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sc.RemoteSignerClient = NewRemoteSignerClient(sc.conn)
|
||||
|
||||
// Start a routine to keep the connection alive
|
||||
sc.cancelPing = make(chan struct{}, 1)
|
||||
|
@@ -25,10 +25,15 @@ func TestSocketPVAddress(t *testing.T) {
|
||||
defer sc.Stop()
|
||||
defer rs.Stop()
|
||||
|
||||
serverAddr := rs.privVal.GetPubKey().Address()
|
||||
clientAddr := sc.GetPubKey().Address()
|
||||
serverAddr := rs.privVal.GetAddress()
|
||||
|
||||
clientAddr := sc.GetAddress()
|
||||
|
||||
assert.Equal(t, serverAddr, clientAddr)
|
||||
|
||||
// TODO(xla): Remove when PrivValidator2 replaced PrivValidator.
|
||||
assert.Equal(t, serverAddr, sc.GetAddress())
|
||||
|
||||
}
|
||||
|
||||
func TestSocketPVPubKey(t *testing.T) {
|
||||
@@ -42,9 +47,12 @@ func TestSocketPVPubKey(t *testing.T) {
|
||||
clientKey, err := sc.getPubKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
privvalPubKey := rs.privVal.GetPubKey()
|
||||
privKey := rs.privVal.GetPubKey()
|
||||
|
||||
assert.Equal(t, privvalPubKey, clientKey)
|
||||
assert.Equal(t, privKey, clientKey)
|
||||
|
||||
// TODO(xla): Remove when PrivValidator2 replaced PrivValidator.
|
||||
assert.Equal(t, privKey, sc.GetPubKey())
|
||||
}
|
||||
|
||||
func TestSocketPVProposal(t *testing.T) {
|
||||
@@ -145,9 +153,9 @@ func TestSocketPVDeadline(t *testing.T) {
|
||||
go func(sc *TCPVal) {
|
||||
defer close(listenc)
|
||||
|
||||
assert.Equal(t, sc.Start().(cmn.Error).Data(), ErrConnTimeout)
|
||||
require.NoError(t, sc.Start())
|
||||
|
||||
assert.False(t, sc.IsRunning())
|
||||
assert.True(t, sc.IsRunning())
|
||||
}(sc)
|
||||
|
||||
for {
|
||||
@@ -166,6 +174,9 @@ func TestSocketPVDeadline(t *testing.T) {
|
||||
}
|
||||
|
||||
<-listenc
|
||||
|
||||
_, err := sc.getPubKey()
|
||||
assert.Equal(t, err.(cmn.Error).Data(), ErrConnTimeout)
|
||||
}
|
||||
|
||||
func TestRemoteSignerRetry(t *testing.T) {
|
||||
@@ -299,15 +310,14 @@ func TestErrUnexpectedResponse(t *testing.T) {
|
||||
testStartSocketPV(t, readyc, sc)
|
||||
defer sc.Stop()
|
||||
RemoteSignerConnDeadline(time.Millisecond)(rs)
|
||||
RemoteSignerConnRetries(100)(rs)
|
||||
RemoteSignerConnRetries(1e6)(rs)
|
||||
|
||||
// we do not want to Start() the remote signer here and instead use the connection to
|
||||
// reply with intentionally wrong replies below:
|
||||
rsConn, err := rs.connect()
|
||||
defer rsConn.Close()
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rsConn)
|
||||
// send over public key to get the remote signer running:
|
||||
go testReadWriteResponse(t, &PubKeyResponse{}, rsConn)
|
||||
<-readyc
|
||||
|
||||
// Proposal:
|
||||
|
@@ -6,7 +6,6 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
abcicli "github.com/tendermint/tendermint/abci/client"
|
||||
"github.com/tendermint/tendermint/abci/example/counter"
|
||||
"github.com/tendermint/tendermint/abci/example/kvstore"
|
||||
"github.com/tendermint/tendermint/abci/types"
|
||||
)
|
||||
@@ -65,15 +64,15 @@ func (r *remoteClientCreator) NewABCIClient() (abcicli.Client, error) {
|
||||
|
||||
func DefaultClientCreator(addr, transport, dbDir string) ClientCreator {
|
||||
switch addr {
|
||||
case "counter":
|
||||
return NewLocalClientCreator(counter.NewCounterApplication(false))
|
||||
case "counter_serial":
|
||||
return NewLocalClientCreator(counter.NewCounterApplication(true))
|
||||
case "kvstore":
|
||||
fallthrough
|
||||
case "dummy":
|
||||
return NewLocalClientCreator(kvstore.NewKVStoreApplication())
|
||||
case "persistent_kvstore":
|
||||
fallthrough
|
||||
case "persistent_dummy":
|
||||
return NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(dbDir))
|
||||
case "noop":
|
||||
case "nilapp":
|
||||
return NewLocalClientCreator(types.NewBaseApplication())
|
||||
default:
|
||||
mustConnect := false // loop retrying
|
||||
|
@@ -18,7 +18,7 @@ const (
|
||||
// TMCoreSemVer is the current version of Tendermint Core.
|
||||
// It's the Semantic Version of the software.
|
||||
// Must be a string because scripts like dist.sh read this file.
|
||||
TMCoreSemVer = "0.27.3"
|
||||
TMCoreSemVer = "0.27.4"
|
||||
|
||||
// ABCISemVer is the semantic version of the ABCI library
|
||||
ABCISemVer = "0.15.0"
|
||||
|
Reference in New Issue
Block a user