mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-22 10:51:20 +00:00
commit
5fdbcd70df
16
CHANGELOG.md
16
CHANGELOG.md
@ -1,6 +1,20 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## TBA
|
## 0.22.6
|
||||||
|
|
||||||
|
*July 24th, 2018*
|
||||||
|
|
||||||
|
BUG FIXES
|
||||||
|
|
||||||
|
- [rpc] Fix `/blockchain` endpoint
|
||||||
|
- (#2049) Fix OOM attack by returning error on negative input
|
||||||
|
- Fix result length to have max 20 (instead of 21) block metas
|
||||||
|
- [rpc] Validate height is non-negative in `/abci_query`
|
||||||
|
- [consensus] (#2050) Include evidence in proposal block parts (previously evidence was
|
||||||
|
not being included in blocks!)
|
||||||
|
- [p2p] (#2046) Close rejected inbound connections so file descriptor doesn't
|
||||||
|
leak
|
||||||
|
- [Gopkg] (#2053) Fix versions in the toml
|
||||||
|
|
||||||
## 0.22.5
|
## 0.22.5
|
||||||
|
|
||||||
|
12
Gopkg.lock
generated
12
Gopkg.lock
generated
@ -11,7 +11,6 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/btcsuite/btcd"
|
name = "github.com/btcsuite/btcd"
|
||||||
packages = ["btcec"]
|
packages = ["btcec"]
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "f673a4b563b57b9a95832545c878669a7fa801d9"
|
revision = "f673a4b563b57b9a95832545c878669a7fa801d9"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
@ -81,8 +80,8 @@
|
|||||||
"sortkeys",
|
"sortkeys",
|
||||||
"types"
|
"types"
|
||||||
]
|
]
|
||||||
revision = "7d68e886eac4f7e34d0d82241a6273d6c304c5cf"
|
revision = "636bf0302bc95575d69441b25a2603156ffdddf1"
|
||||||
version = "v1.1.0"
|
version = "v1.1.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/golang/protobuf"
|
name = "github.com/golang/protobuf"
|
||||||
@ -156,10 +155,8 @@
|
|||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:5ab79470a1d0fb19b041a624415612f8236b3c06070161a910562f2b2d064355"
|
|
||||||
name = "github.com/mitchellh/mapstructure"
|
name = "github.com/mitchellh/mapstructure"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "f15292f7a699fcc1a38a80977f80a046874ba8ac"
|
revision = "f15292f7a699fcc1a38a80977f80a046874ba8ac"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
@ -190,10 +187,8 @@
|
|||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
digest = "1:0f37e09b3e92aaeda5991581311f8dbf38944b36a3edec61cc2d1991f527554a"
|
|
||||||
name = "github.com/prometheus/client_model"
|
name = "github.com/prometheus/client_model"
|
||||||
packages = ["go"]
|
packages = ["go"]
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f"
|
revision = "5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
@ -347,7 +342,6 @@
|
|||||||
"cpu",
|
"cpu",
|
||||||
"unix"
|
"unix"
|
||||||
]
|
]
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "ac767d655b305d4e9612f5f6e33120b9176c4ad4"
|
revision = "ac767d655b305d4e9612f5f6e33120b9176c4ad4"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
@ -417,6 +411,6 @@
|
|||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "9beb2d27dc19e3f9e2c7f416f312f7129f5441b1b53def42503fc6f7d3a54b16"
|
inputs-digest = "8e519c3716c259c6ecdb052889dd3602539fd98a3650dfbf50a4023e087a5d53"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
10
Gopkg.toml
10
Gopkg.toml
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/go-kit/kit"
|
name = "github.com/go-kit/kit"
|
||||||
version = "=0.7.0"
|
version = "=0.6.0"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/gogo/protobuf"
|
name = "github.com/gogo/protobuf"
|
||||||
@ -51,19 +51,19 @@
|
|||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/spf13/cobra"
|
name = "github.com/spf13/cobra"
|
||||||
version = "=0.0.3"
|
version = "=0.0.1"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/spf13/viper"
|
name = "github.com/spf13/viper"
|
||||||
version = "=1.0.2"
|
version = "=1.0.0"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/stretchr/testify"
|
name = "github.com/stretchr/testify"
|
||||||
version = "=1.2.2"
|
version = "=1.2.1"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/tendermint/go-amino"
|
name = "github.com/tendermint/go-amino"
|
||||||
version = "=v0.11.1"
|
version = "=v0.10.1"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "google.golang.org/grpc"
|
name = "google.golang.org/grpc"
|
||||||
|
@ -156,7 +156,7 @@ func makeTxs(height int64) (txs []types.Tx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func makeBlock(height int64, state sm.State) *types.Block {
|
func makeBlock(height int64, state sm.State) *types.Block {
|
||||||
block, _ := state.MakeBlock(height, makeTxs(height), new(types.Commit))
|
block, _ := state.MakeBlock(height, makeTxs(height), new(types.Commit), nil)
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -907,6 +907,8 @@ func (cs *ConsensusState) isProposalComplete() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the next block to propose and return it.
|
// Create the next block to propose and return it.
|
||||||
|
// We really only need to return the parts, but the block
|
||||||
|
// is returned for convenience so we can log the proposal block.
|
||||||
// Returns nil block upon error.
|
// Returns nil block upon error.
|
||||||
// NOTE: keep it side-effect free for clarity.
|
// NOTE: keep it side-effect free for clarity.
|
||||||
func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts *types.PartSet) {
|
func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts *types.PartSet) {
|
||||||
@ -926,9 +928,8 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts
|
|||||||
|
|
||||||
// Mempool validated transactions
|
// Mempool validated transactions
|
||||||
txs := cs.mempool.Reap(cs.state.ConsensusParams.BlockSize.MaxTxs)
|
txs := cs.mempool.Reap(cs.state.ConsensusParams.BlockSize.MaxTxs)
|
||||||
block, parts := cs.state.MakeBlock(cs.Height, txs, commit)
|
|
||||||
evidence := cs.evpool.PendingEvidence()
|
evidence := cs.evpool.PendingEvidence()
|
||||||
block.AddEvidence(evidence)
|
block, parts := cs.state.MakeBlock(cs.Height, txs, commit, evidence)
|
||||||
return block, parts
|
return block, parts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ func (l *DefaultListener) OnStop() {
|
|||||||
l.listener.Close() // nolint: errcheck
|
l.listener.Close() // nolint: errcheck
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accept connections and pass on the channel
|
// Accept connections and pass on the channel.
|
||||||
func (l *DefaultListener) listenRoutine() {
|
func (l *DefaultListener) listenRoutine() {
|
||||||
for {
|
for {
|
||||||
conn, err := l.listener.Accept()
|
conn, err := l.listener.Accept()
|
||||||
@ -178,6 +178,8 @@ func (l *DefaultListener) listenRoutine() {
|
|||||||
|
|
||||||
// Connections returns a channel of inbound connections.
|
// Connections returns a channel of inbound connections.
|
||||||
// It gets closed when the listener closes.
|
// It gets closed when the listener closes.
|
||||||
|
// It is the callers responsibility to close any connections received
|
||||||
|
// over this channel.
|
||||||
func (l *DefaultListener) Connections() <-chan net.Conn {
|
func (l *DefaultListener) Connections() <-chan net.Conn {
|
||||||
return l.connections
|
return l.connections
|
||||||
}
|
}
|
||||||
|
@ -496,6 +496,7 @@ func (sw *Switch) listenerRoutine(l Listener) {
|
|||||||
maxPeers := sw.config.MaxNumPeers - DefaultMinNumOutboundPeers
|
maxPeers := sw.config.MaxNumPeers - DefaultMinNumOutboundPeers
|
||||||
if maxPeers <= sw.peers.Size() {
|
if maxPeers <= sw.peers.Size() {
|
||||||
sw.Logger.Info("Ignoring inbound connection: already have enough peers", "address", inConn.RemoteAddr().String(), "numPeers", sw.peers.Size(), "max", maxPeers)
|
sw.Logger.Info("Ignoring inbound connection: already have enough peers", "address", inConn.RemoteAddr().String(), "numPeers", sw.peers.Size(), "max", maxPeers)
|
||||||
|
inConn.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,6 +511,7 @@ func (sw *Switch) listenerRoutine(l Listener) {
|
|||||||
// cleanup
|
// cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// closes conn if err is returned
|
||||||
func (sw *Switch) addInboundPeerWithConfig(
|
func (sw *Switch) addInboundPeerWithConfig(
|
||||||
conn net.Conn,
|
conn net.Conn,
|
||||||
config *config.P2PConfig,
|
config *config.P2PConfig,
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
abci "github.com/tendermint/tendermint/abci/types"
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
cmn "github.com/tendermint/tendermint/libs/common"
|
||||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||||
"github.com/tendermint/tendermint/version"
|
"github.com/tendermint/tendermint/version"
|
||||||
cmn "github.com/tendermint/tendermint/libs/common"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Query the application for some information.
|
// Query the application for some information.
|
||||||
@ -48,6 +50,10 @@ import (
|
|||||||
// | height | int64 | 0 | false | Height (0 means latest) |
|
// | height | int64 | 0 | false | Height (0 means latest) |
|
||||||
// | trusted | bool | false | false | Does not include a proof of the data inclusion |
|
// | trusted | bool | false | false | Does not include a proof of the data inclusion |
|
||||||
func ABCIQuery(path string, data cmn.HexBytes, height int64, trusted bool) (*ctypes.ResultABCIQuery, error) {
|
func ABCIQuery(path string, data cmn.HexBytes, height int64, trusted bool) (*ctypes.ResultABCIQuery, error) {
|
||||||
|
if height < 0 {
|
||||||
|
return nil, fmt.Errorf("height must be non-negative")
|
||||||
|
}
|
||||||
|
|
||||||
resQuery, err := proxyAppQuery.QuerySync(abci.RequestQuery{
|
resQuery, err := proxyAppQuery.QuerySync(abci.RequestQuery{
|
||||||
Path: path,
|
Path: path,
|
||||||
Data: data,
|
Data: data,
|
||||||
|
@ -64,25 +64,15 @@ import (
|
|||||||
//
|
//
|
||||||
// <aside class="notice">Returns at most 20 items.</aside>
|
// <aside class="notice">Returns at most 20 items.</aside>
|
||||||
func BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
|
func BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
|
||||||
if minHeight == 0 {
|
|
||||||
minHeight = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if maxHeight == 0 {
|
|
||||||
maxHeight = blockStore.Height()
|
|
||||||
} else {
|
|
||||||
maxHeight = cmn.MinInt64(blockStore.Height(), maxHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
// maximum 20 block metas
|
// maximum 20 block metas
|
||||||
const limit int64 = 20
|
const limit int64 = 20
|
||||||
minHeight = cmn.MaxInt64(minHeight, maxHeight-limit)
|
var err error
|
||||||
|
minHeight, maxHeight, err = filterMinMax(blockStore.Height(), minHeight, maxHeight, limit)
|
||||||
logger.Debug("BlockchainInfoHandler", "maxHeight", maxHeight, "minHeight", minHeight)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
if minHeight > maxHeight {
|
|
||||||
return nil, fmt.Errorf("min height %d can't be greater than max height %d", minHeight, maxHeight)
|
|
||||||
}
|
}
|
||||||
|
logger.Debug("BlockchainInfoHandler", "maxHeight", maxHeight, "minHeight", minHeight)
|
||||||
|
|
||||||
blockMetas := []*types.BlockMeta{}
|
blockMetas := []*types.BlockMeta{}
|
||||||
for height := maxHeight; height >= minHeight; height-- {
|
for height := maxHeight; height >= minHeight; height-- {
|
||||||
@ -93,6 +83,37 @@ func BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, e
|
|||||||
return &ctypes.ResultBlockchainInfo{blockStore.Height(), blockMetas}, nil
|
return &ctypes.ResultBlockchainInfo{blockStore.Height(), blockMetas}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// error if either min or max are negative or min < max
|
||||||
|
// if 0, use 1 for min, latest block height for max
|
||||||
|
// enforce limit.
|
||||||
|
// error if min > max
|
||||||
|
func filterMinMax(height, min, max, limit int64) (int64, int64, error) {
|
||||||
|
// filter negatives
|
||||||
|
if min < 0 || max < 0 {
|
||||||
|
return min, max, fmt.Errorf("heights must be non-negative")
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust for default values
|
||||||
|
if min == 0 {
|
||||||
|
min = 1
|
||||||
|
}
|
||||||
|
if max == 0 {
|
||||||
|
max = height
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit max to the height
|
||||||
|
max = cmn.MinInt64(height, max)
|
||||||
|
|
||||||
|
// limit min to within `limit` of max
|
||||||
|
// so the total number of blocks returned will be `limit`
|
||||||
|
min = cmn.MaxInt64(min, max-limit+1)
|
||||||
|
|
||||||
|
if min > max {
|
||||||
|
return min, max, fmt.Errorf("min height %d can't be greater than max height %d", min, max)
|
||||||
|
}
|
||||||
|
return min, max, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Get block at a given height.
|
// Get block at a given height.
|
||||||
// If no height is provided, it will fetch the latest block.
|
// If no height is provided, it will fetch the latest block.
|
||||||
//
|
//
|
||||||
|
58
rpc/core/blocks_test.go
Normal file
58
rpc/core/blocks_test.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBlockchainInfo(t *testing.T) {
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
min, max int64
|
||||||
|
height int64
|
||||||
|
limit int64
|
||||||
|
resultLength int64
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
|
||||||
|
// min > max
|
||||||
|
{0, 0, 0, 10, 0, true}, // min set to 1
|
||||||
|
{0, 1, 0, 10, 0, true}, // max set to height (0)
|
||||||
|
{0, 0, 1, 10, 1, false}, // max set to height (1)
|
||||||
|
{2, 0, 1, 10, 0, true}, // max set to height (1)
|
||||||
|
{2, 1, 5, 10, 0, true},
|
||||||
|
|
||||||
|
// negative
|
||||||
|
{1, 10, 14, 10, 10, false}, // control
|
||||||
|
{-1, 10, 14, 10, 0, true},
|
||||||
|
{1, -10, 14, 10, 0, true},
|
||||||
|
{-9223372036854775808, -9223372036854775788, 100, 20, 0, true},
|
||||||
|
|
||||||
|
// check limit and height
|
||||||
|
{1, 1, 1, 10, 1, false},
|
||||||
|
{1, 1, 5, 10, 1, false},
|
||||||
|
{2, 2, 5, 10, 1, false},
|
||||||
|
{1, 2, 5, 10, 2, false},
|
||||||
|
{1, 5, 1, 10, 1, false},
|
||||||
|
{1, 5, 10, 10, 5, false},
|
||||||
|
{1, 15, 10, 10, 10, false},
|
||||||
|
{1, 15, 15, 10, 10, false},
|
||||||
|
{1, 15, 15, 20, 15, false},
|
||||||
|
{1, 20, 15, 20, 15, false},
|
||||||
|
{1, 20, 20, 20, 20, false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
caseString := fmt.Sprintf("test %d failed", i)
|
||||||
|
min, max, err := filterMinMax(c.height, c.min, c.max, c.limit)
|
||||||
|
if c.wantErr {
|
||||||
|
require.Error(t, err, caseString)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err, caseString)
|
||||||
|
require.Equal(t, 1+max-min, c.resultLength, caseString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -79,7 +79,7 @@ func TestBeginBlockValidators(t *testing.T) {
|
|||||||
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits}
|
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits}
|
||||||
|
|
||||||
// block for height 2
|
// block for height 2
|
||||||
block, _ := state.MakeBlock(2, makeTxs(2), lastCommit)
|
block, _ := state.MakeBlock(2, makeTxs(2), lastCommit, nil)
|
||||||
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
|
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
|
||||||
require.Nil(t, err, tc.desc)
|
require.Nil(t, err, tc.desc)
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
|
|||||||
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: votes}
|
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: votes}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
|
||||||
block, _ := state.MakeBlock(10, makeTxs(2), lastCommit)
|
block, _ := state.MakeBlock(10, makeTxs(2), lastCommit, nil)
|
||||||
block.Time = now
|
block.Time = now
|
||||||
block.Evidence.Evidence = tc.evidence
|
block.Evidence.Evidence = tc.evidence
|
||||||
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
|
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
|
||||||
@ -269,7 +269,7 @@ func state(nVals, height int) (State, dbm.DB) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func makeBlock(state State, height int64) *types.Block {
|
func makeBlock(state State, height int64) *types.Block {
|
||||||
block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit))
|
block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit), nil)
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,18 +101,26 @@ func (state State) GetValidators() (last *types.ValidatorSet, current *types.Val
|
|||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Create a block from the latest state
|
// Create a block from the latest state
|
||||||
|
|
||||||
// MakeBlock builds a block with the given txs and commit from the current state.
|
// MakeBlock builds a block from the current state with the given txs, commit, and evidence.
|
||||||
func (state State) MakeBlock(height int64, txs []types.Tx, commit *types.Commit) (*types.Block, *types.PartSet) {
|
func (state State) MakeBlock(
|
||||||
// build base block
|
height int64,
|
||||||
block := types.MakeBlock(height, txs, commit)
|
txs []types.Tx,
|
||||||
|
commit *types.Commit,
|
||||||
|
evidence []types.Evidence,
|
||||||
|
) (*types.Block, *types.PartSet) {
|
||||||
|
|
||||||
// fill header with state data
|
// Build base block with block data.
|
||||||
|
block := types.MakeBlock(height, txs, commit, evidence)
|
||||||
|
|
||||||
|
// Fill rest of header with state data.
|
||||||
block.ChainID = state.ChainID
|
block.ChainID = state.ChainID
|
||||||
block.TotalTxs = state.LastBlockTotalTx + block.NumTxs
|
|
||||||
block.LastBlockID = state.LastBlockID
|
block.LastBlockID = state.LastBlockID
|
||||||
|
block.TotalTxs = state.LastBlockTotalTx + block.NumTxs
|
||||||
|
|
||||||
block.ValidatorsHash = state.Validators.Hash()
|
block.ValidatorsHash = state.Validators.Hash()
|
||||||
block.AppHash = state.AppHash
|
|
||||||
block.ConsensusHash = state.ConsensusParams.Hash()
|
block.ConsensusHash = state.ConsensusParams.Hash()
|
||||||
|
block.AppHash = state.AppHash
|
||||||
block.LastResultsHash = state.LastResultsHash
|
block.LastResultsHash = state.LastResultsHash
|
||||||
|
|
||||||
return block, block.MakePartSet(state.ConsensusParams.BlockGossip.BlockPartSizeBytes)
|
return block, block.MakePartSet(state.ConsensusParams.BlockGossip.BlockPartSizeBytes)
|
||||||
|
@ -25,7 +25,7 @@ type Block struct {
|
|||||||
|
|
||||||
// MakeBlock returns a new block with an empty header, except what can be computed from itself.
|
// MakeBlock returns a new block with an empty header, except what can be computed from itself.
|
||||||
// It populates the same set of fields validated by ValidateBasic
|
// It populates the same set of fields validated by ValidateBasic
|
||||||
func MakeBlock(height int64, txs []Tx, commit *Commit) *Block {
|
func MakeBlock(height int64, txs []Tx, commit *Commit, evidence []Evidence) *Block {
|
||||||
block := &Block{
|
block := &Block{
|
||||||
Header: Header{
|
Header: Header{
|
||||||
Height: height,
|
Height: height,
|
||||||
@ -35,20 +35,13 @@ func MakeBlock(height int64, txs []Tx, commit *Commit) *Block {
|
|||||||
Data: Data{
|
Data: Data{
|
||||||
Txs: txs,
|
Txs: txs,
|
||||||
},
|
},
|
||||||
|
Evidence: EvidenceData{Evidence: evidence},
|
||||||
LastCommit: commit,
|
LastCommit: commit,
|
||||||
}
|
}
|
||||||
block.fillHeader()
|
block.fillHeader()
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddEvidence appends the given evidence to the block
|
|
||||||
func (b *Block) AddEvidence(evidence []Evidence) {
|
|
||||||
if b == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b.Evidence.Evidence = append(b.Evidence.Evidence, evidence...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateBasic performs basic validation that doesn't involve state data.
|
// ValidateBasic performs basic validation that doesn't involve state data.
|
||||||
// It checks the internal consistency of the block.
|
// It checks the internal consistency of the block.
|
||||||
func (b *Block) ValidateBasic() error {
|
func (b *Block) ValidateBasic() error {
|
||||||
|
@ -19,11 +19,13 @@ func TestBlockAddEvidence(t *testing.T) {
|
|||||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
block := MakeBlock(h, txs, commit)
|
|
||||||
require.NotNil(t, block)
|
|
||||||
|
|
||||||
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
|
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
|
||||||
block.AddEvidence([]Evidence{ev})
|
evList := []Evidence{ev}
|
||||||
|
|
||||||
|
block := MakeBlock(h, txs, commit, evList)
|
||||||
|
require.NotNil(t, block)
|
||||||
|
require.Equal(t, 1, len(block.Evidence.Evidence))
|
||||||
|
require.NotNil(t, block.EvidenceHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBlockValidateBasic(t *testing.T) {
|
func TestBlockValidateBasic(t *testing.T) {
|
||||||
@ -33,11 +35,14 @@ func TestBlockValidateBasic(t *testing.T) {
|
|||||||
lastID := makeBlockIDRandom()
|
lastID := makeBlockIDRandom()
|
||||||
h := int64(3)
|
h := int64(3)
|
||||||
|
|
||||||
voteSet, _, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
|
voteSet, valSet, vals := randVoteSet(h-1, 1, VoteTypePrecommit, 10, 1)
|
||||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
block := MakeBlock(h, txs, commit)
|
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
|
||||||
|
evList := []Evidence{ev}
|
||||||
|
|
||||||
|
block := MakeBlock(h, txs, commit, evList)
|
||||||
require.NotNil(t, block)
|
require.NotNil(t, block)
|
||||||
|
|
||||||
// proper block must pass
|
// proper block must pass
|
||||||
@ -45,39 +50,39 @@ func TestBlockValidateBasic(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// tamper with NumTxs
|
// tamper with NumTxs
|
||||||
block = MakeBlock(h, txs, commit)
|
block = MakeBlock(h, txs, commit, evList)
|
||||||
block.NumTxs++
|
block.NumTxs++
|
||||||
err = block.ValidateBasic()
|
err = block.ValidateBasic()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// remove 1/2 the commits
|
// remove 1/2 the commits
|
||||||
block = MakeBlock(h, txs, commit)
|
block = MakeBlock(h, txs, commit, evList)
|
||||||
block.LastCommit.Precommits = commit.Precommits[:commit.Size()/2]
|
block.LastCommit.Precommits = commit.Precommits[:commit.Size()/2]
|
||||||
block.LastCommit.hash = nil // clear hash or change wont be noticed
|
block.LastCommit.hash = nil // clear hash or change wont be noticed
|
||||||
err = block.ValidateBasic()
|
err = block.ValidateBasic()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// tamper with LastCommitHash
|
// tamper with LastCommitHash
|
||||||
block = MakeBlock(h, txs, commit)
|
block = MakeBlock(h, txs, commit, evList)
|
||||||
block.LastCommitHash = []byte("something else")
|
block.LastCommitHash = []byte("something else")
|
||||||
err = block.ValidateBasic()
|
err = block.ValidateBasic()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// tamper with data
|
// tamper with data
|
||||||
block = MakeBlock(h, txs, commit)
|
block = MakeBlock(h, txs, commit, evList)
|
||||||
block.Data.Txs[0] = Tx("something else")
|
block.Data.Txs[0] = Tx("something else")
|
||||||
block.Data.hash = nil // clear hash or change wont be noticed
|
block.Data.hash = nil // clear hash or change wont be noticed
|
||||||
err = block.ValidateBasic()
|
err = block.ValidateBasic()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// tamper with DataHash
|
// tamper with DataHash
|
||||||
block = MakeBlock(h, txs, commit)
|
block = MakeBlock(h, txs, commit, evList)
|
||||||
block.DataHash = cmn.RandBytes(len(block.DataHash))
|
block.DataHash = cmn.RandBytes(len(block.DataHash))
|
||||||
err = block.ValidateBasic()
|
err = block.ValidateBasic()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// tamper with evidence
|
// tamper with evidence
|
||||||
block = MakeBlock(h, txs, commit)
|
block = MakeBlock(h, txs, commit, evList)
|
||||||
block.EvidenceHash = []byte("something else")
|
block.EvidenceHash = []byte("something else")
|
||||||
err = block.ValidateBasic()
|
err = block.ValidateBasic()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
@ -85,13 +90,13 @@ func TestBlockValidateBasic(t *testing.T) {
|
|||||||
|
|
||||||
func TestBlockHash(t *testing.T) {
|
func TestBlockHash(t *testing.T) {
|
||||||
assert.Nil(t, (*Block)(nil).Hash())
|
assert.Nil(t, (*Block)(nil).Hash())
|
||||||
assert.Nil(t, MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).Hash())
|
assert.Nil(t, MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil, nil).Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBlockMakePartSet(t *testing.T) {
|
func TestBlockMakePartSet(t *testing.T) {
|
||||||
assert.Nil(t, (*Block)(nil).MakePartSet(2))
|
assert.Nil(t, (*Block)(nil).MakePartSet(2))
|
||||||
|
|
||||||
partSet := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).MakePartSet(1024)
|
partSet := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil, nil).MakePartSet(1024)
|
||||||
assert.NotNil(t, partSet)
|
assert.NotNil(t, partSet)
|
||||||
assert.Equal(t, 1, partSet.Total())
|
assert.Equal(t, 1, partSet.Total())
|
||||||
}
|
}
|
||||||
@ -105,7 +110,10 @@ func TestBlockHashesTo(t *testing.T) {
|
|||||||
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
block := MakeBlock(h, []Tx{Tx("Hello World")}, commit)
|
ev := NewMockGoodEvidence(h, 0, valSet.Validators[0].Address)
|
||||||
|
evList := []Evidence{ev}
|
||||||
|
|
||||||
|
block := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList)
|
||||||
block.ValidatorsHash = valSet.Hash()
|
block.ValidatorsHash = valSet.Hash()
|
||||||
assert.False(t, block.HashesTo([]byte{}))
|
assert.False(t, block.HashesTo([]byte{}))
|
||||||
assert.False(t, block.HashesTo([]byte("something else")))
|
assert.False(t, block.HashesTo([]byte("something else")))
|
||||||
@ -113,7 +121,7 @@ func TestBlockHashesTo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBlockSize(t *testing.T) {
|
func TestBlockSize(t *testing.T) {
|
||||||
size := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil).Size()
|
size := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil, nil).Size()
|
||||||
if size <= 0 {
|
if size <= 0 {
|
||||||
t.Fatal("Size of the block is zero or negative")
|
t.Fatal("Size of the block is zero or negative")
|
||||||
}
|
}
|
||||||
@ -124,7 +132,7 @@ func TestBlockString(t *testing.T) {
|
|||||||
assert.Equal(t, "nil-Block", (*Block)(nil).StringIndented(""))
|
assert.Equal(t, "nil-Block", (*Block)(nil).StringIndented(""))
|
||||||
assert.Equal(t, "nil-Block", (*Block)(nil).StringShort())
|
assert.Equal(t, "nil-Block", (*Block)(nil).StringShort())
|
||||||
|
|
||||||
block := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil)
|
block := MakeBlock(int64(3), []Tx{Tx("Hello World")}, nil, nil)
|
||||||
assert.NotEqual(t, "nil-Block", block.String())
|
assert.NotEqual(t, "nil-Block", block.String())
|
||||||
assert.NotEqual(t, "nil-Block", block.StringIndented(""))
|
assert.NotEqual(t, "nil-Block", block.StringIndented(""))
|
||||||
assert.NotEqual(t, "nil-Block", block.StringShort())
|
assert.NotEqual(t, "nil-Block", block.StringShort())
|
||||||
|
@ -4,13 +4,13 @@ package version
|
|||||||
const (
|
const (
|
||||||
Maj = "0"
|
Maj = "0"
|
||||||
Min = "22"
|
Min = "22"
|
||||||
Fix = "5"
|
Fix = "6"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Version is the current version of Tendermint
|
// Version is the current version of Tendermint
|
||||||
// Must be a string because scripts like dist.sh read this file.
|
// Must be a string because scripts like dist.sh read this file.
|
||||||
Version = "0.22.5"
|
Version = "0.22.6"
|
||||||
|
|
||||||
// GitCommit is the current HEAD set using ldflags.
|
// GitCommit is the current HEAD set using ldflags.
|
||||||
GitCommit string
|
GitCommit string
|
||||||
|
Loading…
x
Reference in New Issue
Block a user