mirror of
https://github.com/tendermint/tendermint.git
synced 2026-04-27 02:55:07 +00:00
merge develop and update changelog pending
This commit is contained in:
@@ -7,6 +7,13 @@ defaults: &defaults
|
||||
environment:
|
||||
GOBIN: /tmp/workspace/bin
|
||||
|
||||
docs_update_config: &docs_update_config
|
||||
working_directory: ~/repo
|
||||
docker:
|
||||
- image: tendermint/docs_deployment
|
||||
environment:
|
||||
AWS_REGION: us-east-1
|
||||
|
||||
jobs:
|
||||
setup_dependencies:
|
||||
<<: *defaults
|
||||
@@ -339,10 +346,25 @@ jobs:
|
||||
name: upload
|
||||
command: bash .circleci/codecov.sh -f coverage.txt
|
||||
|
||||
deploy_docs:
|
||||
<<: *docs_update_config
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Trigger website build
|
||||
command: |
|
||||
chamber exec tendermint -- start_website_build
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
test-suite:
|
||||
jobs:
|
||||
- deploy_docs:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- setup_dependencies
|
||||
- lint:
|
||||
requires:
|
||||
|
||||
@@ -8,10 +8,14 @@ Special thanks to external contributors on this release:
|
||||
|
||||
* CLI/RPC/Config
|
||||
|
||||
- [privval] \#2926 split up `PubKeyMsg` into `PubKeyRequest` and `PubKeyResponse` to be consistent with other message types
|
||||
|
||||
* Apps
|
||||
|
||||
* Go API
|
||||
- [types] \#2926 Return error on `PrivValidator.GetAddress()`/`PrivValidator.GetPubKey()` instead of panic'ing
|
||||
* 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
|
||||
- [types] \#2981 Remove `PrivValidator.GetAddress()`
|
||||
|
||||
* Blockchain Protocol
|
||||
|
||||
@@ -20,7 +24,11 @@ Special thanks to external contributors on this release:
|
||||
### FEATURES:
|
||||
|
||||
### IMPROVEMENTS:
|
||||
- [rpc] Add `UnconfirmedTxs(limit)` and `NumUnconfirmedTxs()` methods to HTTP/Local clients (@danil-lashin)
|
||||
- [ci/cd] Updated CircleCI job to trigger website build when docs are updated
|
||||
|
||||
### BUG FIXES:
|
||||
- [kv indexer] \#2912 don't ignore key when executing CONTAINS
|
||||
- [types] \#2926 Return error on `PrivValidator.GetAddress()`/`PrivValidator.GetPubKey()` instead of panic'ing
|
||||
- [types] \#2926 do not panic if retrieving the private validator's public key fails
|
||||
- [mempool] \#2994 Don't allow txs with negative gas wanted
|
||||
- [p2p] \#2715 fix a bug where seeds don't disconnect from a peer after 3h
|
||||
|
||||
@@ -128,14 +128,31 @@ func testnetFiles(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Gather persistent peer addresses.
|
||||
var (
|
||||
persistentPeers string
|
||||
err error
|
||||
)
|
||||
if populatePersistentPeers {
|
||||
err := populatePersistentPeersInConfigAndWriteIt(config)
|
||||
persistentPeers, err = persistentPeersString(config)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(outputDir)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Overwrite default config.
|
||||
for i := 0; i < nValidators+nNonValidators; i++ {
|
||||
nodeDir := filepath.Join(outputDir, fmt.Sprintf("%s%d", nodeDirPrefix, i))
|
||||
config.SetRoot(nodeDir)
|
||||
config.P2P.AddrBookStrict = false
|
||||
if populatePersistentPeers {
|
||||
config.P2P.PersistentPeers = persistentPeers
|
||||
}
|
||||
|
||||
cfg.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), config)
|
||||
}
|
||||
|
||||
fmt.Printf("Successfully initialized %v node directories\n", nValidators+nNonValidators)
|
||||
return nil
|
||||
}
|
||||
@@ -158,28 +175,16 @@ func hostnameOrIP(i int) string {
|
||||
return fmt.Sprintf("%s%d", hostnamePrefix, i)
|
||||
}
|
||||
|
||||
func populatePersistentPeersInConfigAndWriteIt(config *cfg.Config) error {
|
||||
func persistentPeersString(config *cfg.Config) (string, error) {
|
||||
persistentPeers := make([]string, nValidators+nNonValidators)
|
||||
for i := 0; i < nValidators+nNonValidators; i++ {
|
||||
nodeDir := filepath.Join(outputDir, fmt.Sprintf("%s%d", nodeDirPrefix, i))
|
||||
config.SetRoot(nodeDir)
|
||||
nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile())
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
persistentPeers[i] = p2p.IDAddressString(nodeKey.ID(), fmt.Sprintf("%s:%d", hostnameOrIP(i), p2pPort))
|
||||
}
|
||||
persistentPeersList := strings.Join(persistentPeers, ",")
|
||||
|
||||
for i := 0; i < nValidators+nNonValidators; i++ {
|
||||
nodeDir := filepath.Join(outputDir, fmt.Sprintf("%s%d", nodeDirPrefix, i))
|
||||
config.SetRoot(nodeDir)
|
||||
config.P2P.PersistentPeers = persistentPeersList
|
||||
config.P2P.AddrBookStrict = false
|
||||
|
||||
// overwrite default config
|
||||
cfg.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), config)
|
||||
}
|
||||
|
||||
return nil
|
||||
return strings.Join(persistentPeers, ","), nil
|
||||
}
|
||||
|
||||
@@ -8,7 +8,12 @@ module.exports = {
|
||||
lineNumbers: true
|
||||
},
|
||||
themeConfig: {
|
||||
lastUpdated: "Last Updated",
|
||||
lastUpdated: true,
|
||||
algolia: {
|
||||
apiKey: '59f0e2deb984aa9cdf2b3a5fd24ac501',
|
||||
indexName: 'tendermint',
|
||||
debug: false
|
||||
},
|
||||
nav: [{ text: "Back to Tendermint", link: "https://tendermint.com" }],
|
||||
sidebar: [
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ Tendermint blockchain application.
|
||||
|
||||
The following diagram provides a superb example:
|
||||
|
||||
<https://drive.google.com/open?id=1yR2XpRi9YCY9H9uMfcw8-RMJpvDyvjz9>
|
||||

|
||||
|
||||
The end-user application here is the Cosmos Voyager, at the bottom left.
|
||||
Voyager communicates with a REST API exposed by a local Light-Client
|
||||
|
||||
@@ -181,5 +181,13 @@
|
||||
"language": "Javascript",
|
||||
"author": "Dennis McKinnon"
|
||||
}
|
||||
],
|
||||
"aminoLibraries": [
|
||||
{
|
||||
"name": "JS-Amino",
|
||||
"url": "https://github.com/TanNgocDo/Js-Amino",
|
||||
"language": "Javascript",
|
||||
"author": "TanNgocDo"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
# Ecosystem
|
||||
|
||||
The growing list of applications built using various pieces of the
|
||||
Tendermint stack can be found at:
|
||||
Tendermint stack can be found at the [ecosystem page](https://tendermint.com/ecosystem).
|
||||
|
||||
- https://tendermint.com/ecosystem
|
||||
|
||||
We thank the community for their contributions thus far and welcome the
|
||||
We thank the community for their contributions and welcome the
|
||||
addition of new projects. A pull request can be submitted to [this
|
||||
file](https://github.com/tendermint/tendermint/blob/master/docs/app-dev/ecosystem.json)
|
||||
to include your project.
|
||||
|
||||
BIN
docs/imgs/cosmos-tendermint-stack-4k.jpg
Normal file
BIN
docs/imgs/cosmos-tendermint-stack-4k.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 625 KiB |
@@ -70,10 +70,6 @@ Tendermint is in essence similar software, but with two key differences:
|
||||
the application logic that's right for them, from key-value store to
|
||||
cryptocurrency to e-voting platform and beyond.
|
||||
|
||||
The layout of this Tendermint website content is also ripped directly
|
||||
and without shame from [consul.io](https://www.consul.io/) and the other
|
||||
[Hashicorp sites](https://www.hashicorp.com/#tools).
|
||||
|
||||
### Bitcoin, Ethereum, etc.
|
||||
|
||||
Tendermint emerged in the tradition of cryptocurrencies like Bitcoin,
|
||||
|
||||
@@ -14,31 +14,31 @@ please submit them to our [bug bounty](https://tendermint.com/security)!
|
||||
|
||||
### Data Structures
|
||||
|
||||
- [Encoding and Digests](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md)
|
||||
- [Blockchain](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/blockchain.md)
|
||||
- [State](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/state.md)
|
||||
- [Encoding and Digests](./blockchain/encoding.md)
|
||||
- [Blockchain](./blockchain/blockchain.md)
|
||||
- [State](./blockchain/state.md)
|
||||
|
||||
### Consensus Protocol
|
||||
|
||||
- [Consensus Algorithm](/docs/spec/consensus/consensus.md)
|
||||
- [Creating a proposal](/docs/spec/consensus/creating-proposal.md)
|
||||
- [Time](/docs/spec/consensus/bft-time.md)
|
||||
- [Light-Client](/docs/spec/consensus/light-client.md)
|
||||
- [Consensus Algorithm](./consensus/consensus.md)
|
||||
- [Creating a proposal](./consensus/creating-proposal.md)
|
||||
- [Time](./consensus/bft-time.md)
|
||||
- [Light-Client](./consensus/light-client.md)
|
||||
|
||||
### P2P and Network Protocols
|
||||
|
||||
- [The Base P2P Layer](https://github.com/tendermint/tendermint/tree/master/docs/spec/p2p): multiplex the protocols ("reactors") on authenticated and encrypted TCP connections
|
||||
- [Peer Exchange (PEX)](https://github.com/tendermint/tendermint/tree/master/docs/spec/reactors/pex): gossip known peer addresses so peers can find each other
|
||||
- [Block Sync](https://github.com/tendermint/tendermint/tree/master/docs/spec/reactors/block_sync): gossip blocks so peers can catch up quickly
|
||||
- [Consensus](https://github.com/tendermint/tendermint/tree/master/docs/spec/reactors/consensus): gossip votes and block parts so new blocks can be committed
|
||||
- [Mempool](https://github.com/tendermint/tendermint/tree/master/docs/spec/reactors/mempool): gossip transactions so they get included in blocks
|
||||
- Evidence: Forthcoming, see [this issue](https://github.com/tendermint/tendermint/issues/2329).
|
||||
- [The Base P2P Layer](./p2p/): multiplex the protocols ("reactors") on authenticated and encrypted TCP connections
|
||||
- [Peer Exchange (PEX)](./reactors/pex/): gossip known peer addresses so peers can find each other
|
||||
- [Block Sync](./reactors/block_sync/): gossip blocks so peers can catch up quickly
|
||||
- [Consensus](./reactors/consensus/): gossip votes and block parts so new blocks can be committed
|
||||
- [Mempool](./reactors/mempool/): gossip transactions so they get included in blocks
|
||||
- [Evidence](./reactors/evidence/): sending invalid evidence will stop the peer
|
||||
|
||||
### Software
|
||||
|
||||
- [ABCI](/docs/spec/software/abci.md): Details about interactions between the
|
||||
- [ABCI](./software/abci.md): Details about interactions between the
|
||||
application and consensus engine over ABCI
|
||||
- [Write-Ahead Log](/docs/spec/software/wal.md): Details about how the consensus
|
||||
- [Write-Ahead Log](./software/wal.md): Details about how the consensus
|
||||
engine preserves data and recovers from crash failures
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -19,12 +20,22 @@ var (
|
||||
// inside a test (not in the init func) because
|
||||
// verbose flag only set at the time of testing.
|
||||
func TestingLogger() Logger {
|
||||
return TestingLoggerWithOutput(os.Stdout)
|
||||
}
|
||||
|
||||
// TestingLoggerWOutput returns a TMLogger which writes to (w io.Writer) if testing being run
|
||||
// with the verbose (-v) flag, NopLogger otherwise.
|
||||
//
|
||||
// Note that the call to TestingLoggerWithOutput(w io.Writer) must be made
|
||||
// inside a test (not in the init func) because
|
||||
// verbose flag only set at the time of testing.
|
||||
func TestingLoggerWithOutput(w io.Writer) Logger {
|
||||
if _testingLogger != nil {
|
||||
return _testingLogger
|
||||
}
|
||||
|
||||
if testing.Verbose() {
|
||||
_testingLogger = NewTMLogger(NewSyncWriter(os.Stdout))
|
||||
_testingLogger = NewTMLogger(NewSyncWriter(w))
|
||||
} else {
|
||||
_testingLogger = NewNopLogger()
|
||||
}
|
||||
|
||||
@@ -108,6 +108,10 @@ func PostCheckMaxGas(maxGas int64) PostCheckFunc {
|
||||
if maxGas == -1 {
|
||||
return nil
|
||||
}
|
||||
if res.GasWanted < 0 {
|
||||
return fmt.Errorf("gas wanted %d is negative",
|
||||
res.GasWanted)
|
||||
}
|
||||
if res.GasWanted > maxGas {
|
||||
return fmt.Errorf("gas wanted %d is greater than max gas %d",
|
||||
res.GasWanted, maxGas)
|
||||
@@ -486,11 +490,15 @@ func (mem *Mempool) ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs {
|
||||
return txs
|
||||
}
|
||||
totalBytes += int64(len(memTx.tx)) + aminoOverhead
|
||||
// Check total gas requirement
|
||||
if maxGas > -1 && totalGas+memTx.gasWanted > maxGas {
|
||||
// Check total gas requirement.
|
||||
// If maxGas is negative, skip this check.
|
||||
// Since newTotalGas < masGas, which
|
||||
// must be non-negative, it follows that this won't overflow.
|
||||
newTotalGas := totalGas + memTx.gasWanted
|
||||
if maxGas > -1 && newTotalGas > maxGas {
|
||||
return txs
|
||||
}
|
||||
totalGas += memTx.gasWanted
|
||||
totalGas = newTotalGas
|
||||
txs = append(txs, memTx.tx)
|
||||
}
|
||||
return txs
|
||||
|
||||
@@ -160,6 +160,7 @@ func NewMConnectionWithConfig(conn net.Conn, chDescs []*ChannelDescriptor, onRec
|
||||
onReceive: onReceive,
|
||||
onError: onError,
|
||||
config: config,
|
||||
created: time.Now(),
|
||||
}
|
||||
|
||||
// Create channels
|
||||
|
||||
@@ -109,6 +109,24 @@ func (c *HTTP) broadcastTX(route string, tx types.Tx) (*ctypes.ResultBroadcastTx
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) UnconfirmedTxs(limit int) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
result := new(ctypes.ResultUnconfirmedTxs)
|
||||
_, err := c.rpc.Call("unconfirmed_txs", map[string]interface{}{"limit": limit}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "unconfirmed_txs")
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
result := new(ctypes.ResultUnconfirmedTxs)
|
||||
_, err := c.rpc.Call("num_unconfirmed_txs", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "num_unconfirmed_txs")
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *HTTP) NetInfo() (*ctypes.ResultNetInfo, error) {
|
||||
result := new(ctypes.ResultNetInfo)
|
||||
_, err := c.rpc.Call("net_info", map[string]interface{}{}, result)
|
||||
|
||||
@@ -93,3 +93,9 @@ type NetworkClient interface {
|
||||
type EventsClient interface {
|
||||
types.EventBusSubscriber
|
||||
}
|
||||
|
||||
// MempoolClient shows us data about current mempool state.
|
||||
type MempoolClient interface {
|
||||
UnconfirmedTxs(limit int) (*ctypes.ResultUnconfirmedTxs, error)
|
||||
NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,14 @@ func (Local) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return core.BroadcastTxSync(tx)
|
||||
}
|
||||
|
||||
func (Local) UnconfirmedTxs(limit int) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
return core.UnconfirmedTxs(limit)
|
||||
}
|
||||
|
||||
func (Local) NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
return core.NumUnconfirmedTxs()
|
||||
}
|
||||
|
||||
func (Local) NetInfo() (*ctypes.ResultNetInfo, error) {
|
||||
return core.NetInfo()
|
||||
}
|
||||
|
||||
@@ -281,6 +281,42 @@ func TestBroadcastTxCommit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnconfirmedTxs(t *testing.T) {
|
||||
_, _, tx := MakeTxKV()
|
||||
|
||||
mempool := node.MempoolReactor().Mempool
|
||||
_ = mempool.CheckTx(tx, nil)
|
||||
|
||||
for i, c := range GetClients() {
|
||||
mc, ok := c.(client.MempoolClient)
|
||||
require.True(t, ok, "%d", i)
|
||||
txs, err := mc.UnconfirmedTxs(1)
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
assert.Exactly(t, types.Txs{tx}, types.Txs(txs.Txs))
|
||||
}
|
||||
|
||||
mempool.Flush()
|
||||
}
|
||||
|
||||
func TestNumUnconfirmedTxs(t *testing.T) {
|
||||
_, _, tx := MakeTxKV()
|
||||
|
||||
mempool := node.MempoolReactor().Mempool
|
||||
_ = mempool.CheckTx(tx, nil)
|
||||
mempoolSize := mempool.Size()
|
||||
|
||||
for i, c := range GetClients() {
|
||||
mc, ok := c.(client.MempoolClient)
|
||||
require.True(t, ok, "%d", i)
|
||||
res, err := mc.NumUnconfirmedTxs()
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
|
||||
assert.Equal(t, mempoolSize, res.N)
|
||||
}
|
||||
|
||||
mempool.Flush()
|
||||
}
|
||||
|
||||
func TestTx(t *testing.T) {
|
||||
// first we broadcast a tx
|
||||
c := getHTTPClient()
|
||||
|
||||
@@ -147,6 +147,7 @@ func TestVoteVerifySignature(t *testing.T) {
|
||||
|
||||
// sign it
|
||||
err := privVal.SignVote("test_chain_id", vote)
|
||||
require.NoError(t, err)
|
||||
|
||||
// verify the same vote
|
||||
valid := pubkey.VerifyBytes(vote.SignBytes("test_chain_id"), vote.Signature)
|
||||
|
||||
Reference in New Issue
Block a user