removing unnecessary formatting

This commit is contained in:
Sam Ricotta
2022-08-19 14:26:19 +02:00
parent 596ca4e591
commit afaed78146
57 changed files with 303 additions and 334 deletions

View File

@@ -40,5 +40,7 @@ linters-settings:
max-blank-identifiers: 3
golint:
min-confidence: 0
maligned:
suggest-new: true
misspell:
locale: US

View File

@@ -31,7 +31,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
### IMPROVEMENTS
- [config] \#9054 Flag added to overwrite abciresponses.
- [config] \#9054 Configuration flag added to permit Tendermint to discard all ABCIResponses except for the most recent
### BUG FIXES

View File

@@ -2,8 +2,9 @@
Package server is used to start a new ABCI server.
It contains two server implementation:
- gRPC server
- socket server
* gRPC server
* socket server
*/
package server

View File

@@ -410,7 +410,6 @@ func (pool *BlockPool) sendError(err error, peerID p2p.ID) {
}
// for debugging purposes
//
//nolint:unused
func (pool *BlockPool) debug() string {
pool.mtx.Lock()

View File

@@ -291,7 +291,7 @@ func (w *crashingWAL) Start() error { return w.next.Start() }
func (w *crashingWAL) Stop() error { return w.next.Stop() }
func (w *crashingWAL) Wait() { w.next.Wait() }
// ------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
type testSim struct {
GenesisState sm.State
Config *cfg.Config

View File

@@ -978,9 +978,7 @@ func (cs *State) handleTxsAvailable() {
// Used internally by handleTimeout and handleMsg to make state transitions
// Enter: `timeoutNewHeight` by startTime (commitTime+timeoutCommit),
//
// or, if SkipTimeoutCommit==true, after receiving all precommits from (height,round-1)
//
// Enter: `timeoutPrecommits` after any +2/3 precommits from (height,round-1)
// Enter: +2/3 precommits for nil at (height,round-1)
// Enter: +2/3 prevotes any or +2/3 precommits for block or any from (height, round)
@@ -1062,9 +1060,7 @@ func (cs *State) needProofBlock(height int64) bool {
// Enter (CreateEmptyBlocks): from enterNewRound(height,round)
// Enter (CreateEmptyBlocks, CreateEmptyBlocksInterval > 0 ):
//
// after enterNewRound(height,round), after timeout of CreateEmptyBlocksInterval
//
// Enter (!CreateEmptyBlocks) : after enterNewRound(height,round), once txs are in the mempool
func (cs *State) enterPropose(height int64, round int32) {
logger := cs.Logger.With("height", height, "round", round)

View File

@@ -12,19 +12,19 @@ second pre-image attacks. Hence, use this library with caution.
Otherwise you might run into similar issues as, e.g., in early Bitcoin:
https://bitcointalk.org/?topic=102395
*
/ \
/ \
/ \
/ \
* *
/ \ / \
/ \ / \
/ \ / \
* * * h6
/ \ / \ / \
h0 h1 h2 h3 h4 h5
*
/ \
/ \
/ \
/ \
* *
/ \ / \
/ \ / \
/ \ / \
* * * h6
/ \ / \ / \
h0 h1 h2 h3 h4 h5
TODO(ismail): add 2nd pre-image protection or clarify further on how we use this and why this secure.
*/
package merkle

View File

@@ -47,10 +47,10 @@ func HashFromByteSlices(items [][]byte) []byte {
//
// These preliminary results suggest:
//
// 1. The performance of the HashFromByteSlice is pretty good
// 2. Go has low overhead for recursive functions
// 3. The performance of the HashFromByteSlice routine is dominated
// by the actual hashing of data
// 1. The performance of the HashFromByteSlice is pretty good
// 2. Go has low overhead for recursive functions
// 3. The performance of the HashFromByteSlice routine is dominated
// by the actual hashing of data
//
// Although this work is in no way exhaustive, point #3 suggests that
// optimization of this routine would need to take an alternative

View File

@@ -15,7 +15,7 @@ import (
tmjson "github.com/tendermint/tendermint/libs/json"
)
// -------------------------------------
//-------------------------------------
const (
PrivKeyName = "tendermint/PrivKeySecp256k1"
PubKeyName = "tendermint/PubKeySecp256k1"
@@ -124,8 +124,8 @@ func GenPrivKeySecp256k1(secret []byte) PrivKey {
// used to reject malleable signatures
// see:
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1)
// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.

View File

@@ -3,7 +3,7 @@ Package evidence handles all evidence storage and gossiping from detection to bl
For the different types of evidence refer to the `evidence.go` file in the types package
or https://github.com/tendermint/spec/blob/master/spec/consensus/light-client/accountability.md.
# Gossiping
Gossiping
The core functionality begins with the evidence reactor (see reactor.
go) which operates both the sending and receiving of evidence.
@@ -29,7 +29,7 @@ There are two buckets that evidence can be stored in: Pending & Committed.
All evidence is proto encoded to disk.
# Proposing
Proposing
When a new block is being proposed (in state/execution.go#CreateProposalBlock),
`PendingEvidence(maxBytes)` is called to send up to the maxBytes of uncommitted evidence, from the evidence store,
@@ -42,11 +42,12 @@ Once the proposed evidence is submitted,
the evidence is marked as committed and is moved from the broadcasted set to the committed set.
As a result it is also removed from the concurrent list so that it is no longer gossiped.
# Minor Functionality
Minor Functionality
As all evidence (including POLC's) are bounded by an expiration date, those that exceed this are no longer needed
and hence pruned. Currently, only committed evidence in which a marker to the height that the evidence was committed
and hence very small is saved. All updates are made from the `Update(block, state)` function which should be called
when a new block is committed.
*/
package evidence

View File

@@ -102,13 +102,12 @@ func (evpool *Pool) verify(evidence types.Evidence) error {
// VerifyLightClientAttack verifies LightClientAttackEvidence against the state of the full node. This involves
// the following checks:
// - the common header from the full node has at least 1/3 voting power which is also present in
// the conflicting header's commit
// - 2/3+ of the conflicting validator set correctly signed the conflicting block
// - the nodes trusted header at the same height as the conflicting header has a different hash
// - the common header from the full node has at least 1/3 voting power which is also present in
// the conflicting header's commit
// - 2/3+ of the conflicting validator set correctly signed the conflicting block
// - the nodes trusted header at the same height as the conflicting header has a different hash
//
// CONTRACT: must run ValidateBasic() on the evidence before verifying
//
// must check that the evidence has not expired (i.e. is outside the maximum age threshold)
func VerifyLightClientAttack(e *types.LightClientAttackEvidence, commonHeader, trustedHeader *types.SignedHeader,
commonVals *types.ValidatorSet, now time.Time, trustPeriod time.Duration) error {
@@ -155,10 +154,10 @@ func VerifyLightClientAttack(e *types.LightClientAttackEvidence, commonHeader, t
// VerifyDuplicateVote verifies DuplicateVoteEvidence against the state of full node. This involves the
// following checks:
// - the validator is in the validator set at the height of the evidence
// - the height, round, type and validator address of the votes must be the same
// - the block ID's must be different
// - The signatures must both be valid
// - the validator is in the validator set at the height of the evidence
// - the height, round, type and validator address of the votes must be the same
// - the block ID's must be different
// - The signatures must both be valid
func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet *types.ValidatorSet) error {
_, val := valSet.GetByAddress(e.VoteA.ValidatorAddress)
if val == nil {

View File

@@ -17,7 +17,6 @@ const (
// all other modules).
//
// Example:
//
// ParseLogLevel("consensus:debug,mempool:debug,*:error", log.NewTMLogger(os.Stdout), "info")
func ParseLogLevel(lvl string, logger log.Logger, defaultLogLevelValue string) (log.Logger, error) {
if lvl == "" {

View File

@@ -24,6 +24,7 @@ import (
const MaxLength = int(^uint(0) >> 1)
/*
CElement is an element of a linked-list
Traversal from a CElement is goroutine-safe.
@@ -40,6 +41,7 @@ the for-loop. Use sync.Cond when you need serial access to the
"condition". In our case our condition is if `next != nil || removed`,
and there's no reason to serialize that condition for goroutines
waiting on NextWait() (since it's just a read operation).
*/
type CElement struct {
mtx tmsync.RWMutex

View File

@@ -68,7 +68,6 @@ func TestSmall(t *testing.T) {
// This test is quite hacky because it relies on SetFinalizer
// which isn't guaranteed to run at all.
//
//nolint:unused,deadcode
func _TestGCFifo(t *testing.T) {
if runtime.GOARCH != "amd64" {
@@ -118,7 +117,6 @@ func _TestGCFifo(t *testing.T) {
// This test is quite hacky because it relies on SetFinalizer
// which isn't guaranteed to run at all.
//
//nolint:unused,deadcode
func _TestGCRandom(t *testing.T) {
if runtime.GOARCH != "amd64" {

View File

@@ -39,10 +39,10 @@ type Monitor struct {
// weight of each sample in the exponential moving average (EMA) calculation.
// The exact formulas are:
//
// sampleTime = currentTime - prevSampleTime
// sampleRate = byteCount / sampleTime
// weight = 1 - exp(-sampleTime/windowSize)
// newRate = weight*sampleRate + (1-weight)*oldRate
// sampleTime = currentTime - prevSampleTime
// sampleRate = byteCount / sampleTime
// weight = 1 - exp(-sampleTime/windowSize)
// newRate = weight*sampleRate + (1-weight)*oldRate
//
// The default values for sampleRate and windowSize (if <= 0) are 100ms and 1s,
// respectively.

View File

@@ -13,12 +13,12 @@
// compatibility with e.g. Javascript (which uses 64-bit floats for numbers, having 53-bit
// precision):
//
// int32(32) // Output: 32
// uint32(32) // Output: 32
// int64(64) // Output: "64"
// uint64(64) // Output: "64"
// int(64) // Output: "64"
// uint(64) // Output: "64"
// int32(32) // Output: 32
// uint32(32) // Output: 32
// int64(64) // Output: "64"
// uint64(64) // Output: "64"
// int(64) // Output: "64"
// uint(64) // Output: "64"
//
// Encoding of other scalars follows encoding/json:
//
@@ -50,7 +50,7 @@
// Times are encoded as encoding/json, in RFC3339Nano format, but requiring UTC time zone (with zero
// times emitted as "0001-01-01T00:00:00Z" as with encoding/json):
//
// time.Date(2020, 6, 8, 16, 21, 28, 123, time.FixedZone("UTC+2", 2*60*60))
// time.Date(2020, 6, 8, 16, 21, 28, 123, time.FixedZone("UTC+2", 2*60*60))
// // Output: "2020-06-08T14:21:28.000000123Z"
// time.Time{} // Output: "0001-01-01T00:00:00Z"
// (*time.Time)(nil) // Output: null
@@ -95,4 +95,5 @@
//
// Struct{Car: &Car{Wheels: 4}, Vehicle: &Car{Wheels: 4}}
// // Output: {"Car": {"Wheels: 4"}, "Vehicle": {"type":"vehicle/car","value":{"Wheels":4}}}
//
package json

View File

@@ -69,19 +69,18 @@ func (l *filter) Error(msg string, keyvals ...interface{}) {
// Allow*With methods, it is used as the logger's level.
//
// Examples:
// logger = log.NewFilter(logger, log.AllowError(), log.AllowInfoWith("module", "crypto"))
// logger.With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto"
//
// logger = log.NewFilter(logger, log.AllowError(), log.AllowInfoWith("module", "crypto"))
// logger.With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto"
// logger = log.NewFilter(logger, log.AllowError(),
// log.AllowInfoWith("module", "crypto"),
// log.AllowNoneWith("user", "Sam"))
// logger.With("module", "crypto", "user", "Sam").Info("Hello") # returns nil
//
// logger = log.NewFilter(logger, log.AllowError(),
// log.AllowInfoWith("module", "crypto"),
// log.AllowNoneWith("user", "Sam"))
// logger.With("module", "crypto", "user", "Sam").Info("Hello") # returns nil
//
// logger = log.NewFilter(logger,
// log.AllowError(),
// log.AllowInfoWith("module", "crypto"), log.AllowNoneWith("user", "Sam"))
// logger.With("user", "Sam").With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto user=Sam"
// logger = log.NewFilter(logger,
// log.AllowError(),
// log.AllowInfoWith("module", "crypto"), log.AllowNoneWith("user", "Sam"))
// logger.With("user", "Sam").With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto user=Sam"
func (l *filter) With(keyvals ...interface{}) Logger {
keyInAllowedKeyvals := false

View File

@@ -22,9 +22,9 @@ type Logger interface {
//
// If w implements the following interface, so does the returned writer.
//
// interface {
// Fd() uintptr
// }
// interface {
// Fd() uintptr
// }
func NewSyncWriter(w io.Writer) io.Writer {
return kitlog.NewSyncWriter(w)
}

View File

@@ -83,7 +83,7 @@ func benchmarkRunnerKitlog(b *testing.B, logger kitlog.Logger, f func(kitlog.Log
}
}
// nolint: errcheck // ignore errors
//nolint: errcheck // ignore errors
var (
baseMessage = func(logger kitlog.Logger) { logger.Log("foo_key", "foo_value") }
withMessage = func(logger kitlog.Logger) { kitlog.With(logger, "a", "b").Log("d", "f") }

View File

@@ -12,25 +12,25 @@
//
// Example:
//
// q, err := query.New("account.name='John'")
// if err != nil {
// return err
// }
// ctx, cancel := context.WithTimeout(context.Background(), 1 * time.Second)
// defer cancel()
// subscription, err := pubsub.Subscribe(ctx, "johns-transactions", q)
// if err != nil {
// return err
// }
// q, err := query.New("account.name='John'")
// if err != nil {
// return err
// }
// ctx, cancel := context.WithTimeout(context.Background(), 1 * time.Second)
// defer cancel()
// subscription, err := pubsub.Subscribe(ctx, "johns-transactions", q)
// if err != nil {
// return err
// }
//
// for {
// select {
// case msg <- subscription.Out():
// // handle msg.Data() and msg.Events()
// case <-subscription.Cancelled():
// return subscription.Err()
// }
// }
// for {
// select {
// case msg <- subscription.Out():
// // handle msg.Data() and msg.Events()
// case <-subscription.Cancelled():
// return subscription.Err()
// }
// }
package pubsub
import (

View File

@@ -1,6 +1,6 @@
// Package query provides a parser for a custom query format:
//
// abci.invoice.number=22 AND abci.invoice.owner=Ivan
// abci.invoice.number=22 AND abci.invoice.owner=Ivan
//
// See query.peg for the grammar, which is a https://en.wikipedia.org/wiki/Parsing_expression_grammar.
// More: https://github.com/PhilippeSigaud/Pegged/wiki/PEG-Basics

View File

@@ -54,8 +54,7 @@ func (s *Subscription) Cancelled() <-chan struct{} {
// If the channel is closed, Err returns a non-nil error explaining why:
// - ErrUnsubscribed if the subscriber choose to unsubscribe,
// - ErrOutOfCapacity if the subscriber is not pulling messages fast enough
// and the channel returned by Out became full,
//
// and the channel returned by Out became full,
// After Err returns a non-nil error, successive calls to Err return the same
// error.
func (s *Subscription) Err() error {

View File

@@ -284,16 +284,16 @@ func (c *Client) restoreTrustedLightBlock() error {
// if options.Height:
//
// 1. ahead of trustedLightBlock.Height => fetch light blocks (same height as
// 1) ahead of trustedLightBlock.Height => fetch light blocks (same height as
// trustedLightBlock) from primary provider and check it's hash matches the
// trustedLightBlock's hash (if not, remove trustedLightBlock and all the light blocks
// before)
//
// 2. equals trustedLightBlock.Height => check options.Hash matches the
// 2) equals trustedLightBlock.Height => check options.Hash matches the
// trustedLightBlock's hash (if not, remove trustedLightBlock and all the light blocks
// before)
//
// 3. behind trustedLightBlock.Height => remove all the light blocks between
// 3) behind trustedLightBlock.Height => remove all the light blocks between
// options.Height and trustedLightBlock.Height, update trustedLightBlock, then
// check options.Hash matches the trustedLightBlock's hash (if not, remove
// trustedLightBlock and all the light blocks before)
@@ -395,10 +395,10 @@ func (c *Client) initializeWithTrustOptions(ctx context.Context, options TrustOp
// TrustedLightBlock returns a trusted light block at the given height (0 - the latest).
//
// It returns an error if:
// - there are some issues with the trusted store, although that should not
// happen normally;
// - negative height is passed;
// - header has not been verified yet and is therefore not in the store
// - there are some issues with the trusted store, although that should not
// happen normally;
// - negative height is passed;
// - header has not been verified yet and is therefore not in the store
//
// Safe for concurrent use by multiple goroutines.
func (c *Client) TrustedLightBlock(height int64) (*types.LightBlock, error) {
@@ -510,9 +510,8 @@ func (c *Client) VerifyLightBlockAtHeight(ctx context.Context, height int64, now
//
// If the header, which is older than the currently trusted header, is
// requested and the light client does not have it, VerifyHeader will perform:
//
// a) verifySkipping verification if nearest trusted header is found & not expired
// b) backwards verification in all other cases
// a) verifySkipping verification if nearest trusted header is found & not expired
// b) backwards verification in all other cases
//
// It returns ErrOldHeaderExpired if the latest trusted header expired.
//
@@ -981,12 +980,12 @@ func (c *Client) backwards(
// lightBlockFromPrimary retrieves the lightBlock from the primary provider
// at the specified height. This method also handles provider behavior as follows:
//
// 1. If the provider does not respond or does not have the block, it tries again
// with a different provider
// 2. If all providers return the same error, the light client forwards the error to
// where the initial request came from
// 3. If the provider provides an invalid light block, is deemed unreliable or returns
// any other error, the primary is permanently dropped and is replaced by a witness.
// 1. If the provider does not respond or does not have the block, it tries again
// with a different provider
// 2. If all providers return the same error, the light client forwards the error to
// where the initial request came from
// 3. If the provider provides an invalid light block, is deemed unreliable or returns
// any other error, the primary is permanently dropped and is replaced by a witness.
func (c *Client) lightBlockFromPrimary(ctx context.Context, height int64) (*types.LightBlock, error) {
c.providerMutex.Lock()
l, err := c.primary.LightBlock(ctx, height)

View File

@@ -109,9 +109,7 @@ func (c *Client) detectDivergence(ctx context.Context, primaryTrace []*types.Lig
//
// 1: errConflictingHeaders -> there may have been an attack on this light client
// 2: errBadWitness -> the witness has either not responded, doesn't have the header or has given us an invalid one
//
// Note: In the case of an invalid header we remove the witness
//
// Note: In the case of an invalid header we remove the witness
// 3: nil -> the hashes of the two headers match
func (c *Client) compareNewHeaderWithWitness(ctx context.Context, errc chan error, h *types.SignedHeader,
witness provider.Provider, witnessIndex int) {
@@ -277,16 +275,16 @@ func (c *Client) handleConflictingHeaders(
// it has received from another and preforms verifySkipping at the heights of each of the intermediate
// headers in the trace until it reaches the divergentHeader. 1 of 2 things can happen.
//
// 1. The light client verifies a header that is different to the intermediate header in the trace. This
// is the bifurcation point and the light client can create evidence from it
// 2. The source stops responding, doesn't have the block or sends an invalid header in which case we
// return the error and remove the witness
// 1. The light client verifies a header that is different to the intermediate header in the trace. This
// is the bifurcation point and the light client can create evidence from it
// 2. The source stops responding, doesn't have the block or sends an invalid header in which case we
// return the error and remove the witness
//
// CONTRACT:
// 1. Trace can not be empty len(trace) > 0
// 2. The last block in the trace can not be of a lower height than the target block
// trace[len(trace)-1].Height >= targetBlock.Height
// 3. The
// 1. Trace can not be empty len(trace) > 0
// 2. The last block in the trace can not be of a lower height than the target block
// trace[len(trace)-1].Height >= targetBlock.Height
// 3. The
func (c *Client) examineConflictingHeaderAgainstTrace(
ctx context.Context,
trace []*types.LightBlock,

View File

@@ -63,31 +63,29 @@ This package provides three major things:
Example usage:
db, err := dbm.NewGoLevelDB("light-client-db", dbDir)
if err != nil {
// handle error
}
c, err := NewHTTPClient(
chainID,
TrustOptions{
Period: 504 * time.Hour, // 21 days
Height: 100,
Hash: header.Hash(),
},
"http://localhost:26657",
[]string{"http://witness1:26657"},
dbs.New(db, ""),
)
if err != nil {
// handle error
}
h, err := c.TrustedHeader(100)
if err != nil {
// handle error
}
fmt.Println("header", h)
db, err := dbm.NewGoLevelDB("light-client-db", dbDir)
if err != nil {
// handle error
}
c, err := NewHTTPClient(
chainID,
TrustOptions{
Period: 504 * time.Hour, // 21 days
Height: 100,
Hash: header.Hash(),
},
"http://localhost:26657",
[]string{"http://witness1:26657"},
dbs.New(db, ""),
)
if err != nil {
// handle error
}
h, err := c.TrustedHeader(100)
if err != nil {
// handle error
}
fmt.Println("header", h)
Check out other examples in example_test.go

View File

@@ -27,7 +27,6 @@ var errNegOrZeroHeight = errors.New("negative or zero height")
type KeyPathFunc func(path string, key []byte) (merkle.KeyPath, error)
// LightClient is an interface that contains functionality needed by Client from the light client.
//
//go:generate ../../scripts/mockery_generate.sh LightClient
type LightClient interface {
ChainID() string

View File

@@ -19,13 +19,13 @@ var (
// VerifyNonAdjacent verifies non-adjacent untrustedHeader against
// trustedHeader. It ensures that:
//
// a) trustedHeader can still be trusted (if not, ErrOldHeaderExpired is returned)
// b) untrustedHeader is valid (if not, ErrInvalidHeader is returned)
// c) trustLevel ([1/3, 1]) of trustedHeaderVals (or trustedHeaderNextVals)
// signed correctly (if not, ErrNewValSetCantBeTrusted is returned)
// d) more than 2/3 of untrustedVals have signed h2
// (otherwise, ErrInvalidHeader is returned)
// e) headers are non-adjacent.
// a) trustedHeader can still be trusted (if not, ErrOldHeaderExpired is returned)
// b) untrustedHeader is valid (if not, ErrInvalidHeader is returned)
// c) trustLevel ([1/3, 1]) of trustedHeaderVals (or trustedHeaderNextVals)
// signed correctly (if not, ErrNewValSetCantBeTrusted is returned)
// d) more than 2/3 of untrustedVals have signed h2
// (otherwise, ErrInvalidHeader is returned)
// e) headers are non-adjacent.
//
// maxClockDrift defines how much untrustedHeader.Time can drift into the
// future.
@@ -81,12 +81,12 @@ func VerifyNonAdjacent(
// VerifyAdjacent verifies directly adjacent untrustedHeader against
// trustedHeader. It ensures that:
//
// a) trustedHeader can still be trusted (if not, ErrOldHeaderExpired is returned)
// b) untrustedHeader is valid (if not, ErrInvalidHeader is returned)
// c) untrustedHeader.ValidatorsHash equals trustedHeader.NextValidatorsHash
// d) more than 2/3 of new validators (untrustedVals) have signed h2
// (otherwise, ErrInvalidHeader is returned)
// e) headers are adjacent.
// a) trustedHeader can still be trusted (if not, ErrOldHeaderExpired is returned)
// b) untrustedHeader is valid (if not, ErrInvalidHeader is returned)
// c) untrustedHeader.ValidatorsHash equals trustedHeader.NextValidatorsHash
// d) more than 2/3 of new validators (untrustedVals) have signed h2
// (otherwise, ErrInvalidHeader is returned)
// e) headers are adjacent.
//
// maxClockDrift defines how much untrustedHeader.Time can drift into the
// future.
@@ -212,12 +212,12 @@ func HeaderExpired(h *types.SignedHeader, trustingPeriod time.Duration, now time
// VerifyBackwards verifies an untrusted header with a height one less than
// that of an adjacent trusted header. It ensures that:
//
// a) untrusted header is valid
// b) untrusted header has a time before the trusted header
// c) that the LastBlockID hash of the trusted header is the same as the hash
// of the trusted header
// a) untrusted header is valid
// b) untrusted header has a time before the trusted header
// c) that the LastBlockID hash of the trusted header is the same as the hash
// of the trusted header
//
// For any of these cases ErrInvalidHeader is returned.
// For any of these cases ErrInvalidHeader is returned.
func VerifyBackwards(untrustedHeader, trustedHeader *types.Header) error {
if err := untrustedHeader.ValidateBasic(); err != nil {
return ErrInvalidHeader{err}

View File

@@ -194,9 +194,7 @@ func (mem *CListMempool) TxsWaitChan() <-chan struct{} {
// It blocks if we're waiting on Update() or Reap().
// cb: A callback from the CheckTx command.
//
// It gets called from another goroutine.
//
// It gets called from another goroutine.
// CONTRACT: Either cb will get called, or err returned.
//
// Safe for concurrent use by multiple goroutines.
@@ -312,7 +310,7 @@ func (mem *CListMempool) reqResCb(
}
// Called from:
// - resCbFirstTime (lock not held) if tx is valid
// - resCbFirstTime (lock not held) if tx is valid
func (mem *CListMempool) addTx(memTx *mempoolTx) {
e := mem.txs.PushBack(memTx)
mem.txsMap.Store(memTx.tx.Key(), e)
@@ -321,8 +319,8 @@ func (mem *CListMempool) addTx(memTx *mempoolTx) {
}
// Called from:
// - Update (lock held) if tx was committed
// - resCbRecheck (lock not held) if tx was invalidated
// - Update (lock held) if tx was committed
// - resCbRecheck (lock not held) if tx was invalidated
func (mem *CListMempool) removeTx(tx types.Tx, elem *clist.CElement, removeFromCache bool) {
mem.txs.Remove(elem)
elem.DetachPrev()

View File

@@ -6,34 +6,35 @@ Adding new p2p.Reactor(s)
To add a new p2p.Reactor, use the CustomReactors option:
node, err := NewNode(
config,
privVal,
nodeKey,
clientCreator,
genesisDocProvider,
dbProvider,
metricsProvider,
logger,
CustomReactors(map[string]p2p.Reactor{"CUSTOM": customReactor}),
)
node, err := NewNode(
config,
privVal,
nodeKey,
clientCreator,
genesisDocProvider,
dbProvider,
metricsProvider,
logger,
CustomReactors(map[string]p2p.Reactor{"CUSTOM": customReactor}),
)
Replacing existing p2p.Reactor(s)
To replace the built-in p2p.Reactor, use the CustomReactors option:
node, err := NewNode(
config,
privVal,
nodeKey,
clientCreator,
genesisDocProvider,
dbProvider,
metricsProvider,
logger,
CustomReactors(map[string]p2p.Reactor{"BLOCKCHAIN": customBlockchainReactor}),
)
node, err := NewNode(
config,
privVal,
nodeKey,
clientCreator,
genesisDocProvider,
dbProvider,
metricsProvider,
logger,
CustomReactors(map[string]p2p.Reactor{"BLOCKCHAIN": customBlockchainReactor}),
)
The list of existing reactors can be found in CustomReactors documentation.
*/
package node

View File

@@ -145,12 +145,12 @@ type blockSyncReactor interface {
// WARNING: using any name from the below list of the existing reactors will
// result in replacing it with the custom one.
//
// - MEMPOOL
// - BLOCKCHAIN
// - CONSENSUS
// - EVIDENCE
// - PEX
// - STATESYNC
// - MEMPOOL
// - BLOCKCHAIN
// - CONSENSUS
// - EVIDENCE
// - PEX
// - STATESYNC
func CustomReactors(reactors map[string]p2p.Reactor) Option {
return func(n *Node) {
for name, reactor := range reactors {

View File

@@ -10,13 +10,9 @@ import (
// Only Go1.10 has a proper net.Conn implementation that
// has the SetDeadline method implemented as per
//
// https://github.com/golang/go/commit/e2dd8ca946be884bb877e074a21727f1a685a706
//
// https://github.com/golang/go/commit/e2dd8ca946be884bb877e074a21727f1a685a706
// lest we run into problems like
//
// https://github.com/tendermint/tendermint/issues/851
//
// https://github.com/tendermint/tendermint/issues/851
// so for go versions < Go1.10 use our custom net.Conn creator
// that doesn't return an `Unimplemented error` for net.Conn.
// Before https://github.com/tendermint/tendermint/commit/49faa79bdce5663894b3febbf4955fb1d172df04

View File

@@ -62,7 +62,6 @@ The byte id and the relative priorities of each `Channel` are configured upon
initialization of the connection.
There are two methods for sending messages:
func (m MConnection) Send(chID byte, msgBytes []byte) bool {}
func (m MConnection) TrySend(chID byte, msgBytes []byte}) bool {}

View File

@@ -94,16 +94,16 @@ func (ka *knownAddress) removeBucketRef(bucketIdx int) int {
}
/*
An address is bad if the address in question is a New address, has not been tried in the last
minute, and meets one of the following criteria:
An address is bad if the address in question is a New address, has not been tried in the last
minute, and meets one of the following criteria:
1) It claims to be from the future
2) It hasn't been seen in over a week
3) It has failed at least three times and never succeeded
4) It has failed ten times in the last week
1) It claims to be from the future
2) It hasn't been seen in over a week
3) It has failed at least three times and never succeeded
4) It has failed ten times in the last week
All addresses that meet these criteria are assumed to be worthless and not
worth keeping hold of.
All addresses that meet these criteria are assumed to be worthless and not
worth keeping hold of.
*/
func (ka *knownAddress) isBad() bool {
// Is Old --> good

View File

@@ -58,7 +58,6 @@ func TestPEXReactorAddRemovePeer(t *testing.T) {
}
// --- FAIL: TestPEXReactorRunning (11.10s)
//
// pex_reactor_test.go:411: expected all switches to be connected to at
// least one peer (switches: 0 => {outbound: 1, inbound: 0}, 1 =>
// {outbound: 0, inbound: 1}, 2 => {outbound: 0, inbound: 0}, )
@@ -67,6 +66,7 @@ func TestPEXReactorAddRemovePeer(t *testing.T) {
// if any peer (who we already connected to) has the same IP. Even though local
// peers have different IP addresses, they all have the same underlying remote
// IP: 127.0.0.1.
//
func TestPEXReactorRunning(t *testing.T) {
N := 3
switches := make([]*p2p.Switch, N)

View File

@@ -379,8 +379,8 @@ func (sw *Switch) stopAndRemovePeer(peer Peer, reason interface{}) {
// to the PEX/Addrbook to find the peer with the addr again
// NOTE: this will keep trying even if the handshake or auth fails.
// TODO: be more explicit with error types so we only retry on certain failures
// - ie. if we're getting ErrDuplicatePeer we can stop
// because the addrbook got us the peer back already
// - ie. if we're getting ErrDuplicatePeer we can stop
// because the addrbook got us the peer back already
func (sw *Switch) reconnectToPeer(addr *NetAddress) {
if sw.reconnecting.Has(string(addr.ID)) {
return

View File

@@ -72,7 +72,6 @@ func TestTrustMetricCopyNilPointer(t *testing.T) {
}
// XXX: This test fails non-deterministically
//
//nolint:unused,deadcode
func _TestTrustMetricStopPause(t *testing.T) {
// The TestTicker will provide manual control over

View File

@@ -1,12 +1,13 @@
/*
Package privval provides different implementations of the types.PrivValidator.
# FilePV
FilePV
FilePV is the simplest implementation and developer default.
It uses one file for the private key and another to store state.
# SignerListenerEndpoint
SignerListenerEndpoint
SignerListenerEndpoint establishes a connection to an external process,
like a Key Management Server (KMS), using a socket.
@@ -14,14 +15,15 @@ SignerListenerEndpoint listens for the external KMS process to dial in.
SignerListenerEndpoint takes a listener, which determines the type of connection
(ie. encrypted over tcp, or unencrypted over unix).
# SignerDialerEndpoint
SignerDialerEndpoint
SignerDialerEndpoint is a simple wrapper around a net.Conn. It's used by both IPCVal and TCPVal.
# SignerClient
SignerClient
SignerClient handles remote validator connections that provide signing services.
In production, it's recommended to wrap it with RetrySignerClient to avoid
termination in case of temporary errors.
*/
package privval

View File

@@ -39,24 +39,24 @@ the example for more details.
Example:
c, err := New("http://192.168.1.10:26657", "/websocket")
if err != nil {
// handle error
}
c, err := New("http://192.168.1.10:26657", "/websocket")
if err != nil {
// handle error
}
// call Start/Stop if you're subscribing to events
err = c.Start()
if err != nil {
// handle error
}
defer c.Stop()
// call Start/Stop if you're subscribing to events
err = c.Start()
if err != nil {
// handle error
}
defer c.Stop()
res, err := c.Status()
if err != nil {
// handle error
}
res, err := c.Status()
if err != nil {
// handle error
}
// handle result
// handle result
*/
type HTTP struct {
remote string

View File

@@ -47,6 +47,7 @@ var _ client.Client = Client{}
// Call is used by recorders to save a call and response.
// It can also be used to configure mock responses.
//
type Call struct {
Name string
Args interface{}

View File

@@ -69,7 +69,7 @@ type peers interface {
Peers() p2p.IPeerSet
}
// ----------------------------------------------
//----------------------------------------------
// Environment contains objects and interfaces used by the RPC. It is expected
// to be setup once during startup.
type Environment struct {

View File

@@ -1,7 +1,7 @@
// HTTP RPC server supporting calls via uri params, jsonrpc over HTTP, and jsonrpc over
// websockets
//
// # Client Requests
// Client Requests
//
// Suppose we want to expose the rpc function `HelloWorld(name string, num int)`.
//
@@ -9,12 +9,12 @@
//
// As a GET request, it would have URI encoded parameters, and look like:
//
// curl 'http://localhost:8008/hello_world?name="my_world"&num=5'
// curl 'http://localhost:8008/hello_world?name="my_world"&num=5'
//
// Note the `'` around the url, which is just so bash doesn't ignore the quotes in `"my_world"`.
// This should also work:
//
// curl http://localhost:8008/hello_world?name=\"my_world\"&num=5
// curl http://localhost:8008/hello_world?name=\"my_world\"&num=5
//
// A GET request to `/` returns a list of available endpoints.
// For those which take arguments, the arguments will be listed in order, with `_` where the actual value should be.
@@ -23,19 +23,19 @@
//
// As a POST request, we use JSONRPC. For instance, the same request would have this as the body:
//
// {
// "jsonrpc": "2.0",
// "id": "anything",
// "method": "hello_world",
// "params": {
// "name": "my_world",
// "num": 5
// }
// }
// {
// "jsonrpc": "2.0",
// "id": "anything",
// "method": "hello_world",
// "params": {
// "name": "my_world",
// "num": 5
// }
// }
//
// With the above saved in file `data.json`, we can make the request with
//
// curl --data @data.json http://localhost:8008
// curl --data @data.json http://localhost:8008
//
// WebSocket (JSONRPC)
//
@@ -43,42 +43,42 @@
// Websocket connections are available at their own endpoint, typically `/websocket`,
// though this is configurable when starting the server.
//
// # Server Definition
// Server Definition
//
// Define some types and routes:
//
// type ResultStatus struct {
// Value string
// Value string
// }
//
// Define some routes
//
// var Routes = map[string]*rpcserver.RPCFunc{
// "status": rpcserver.NewRPCFunc(Status, "arg"),
// }
// var Routes = map[string]*rpcserver.RPCFunc{
// "status": rpcserver.NewRPCFunc(Status, "arg"),
// }
//
// An rpc function:
//
// func Status(v string) (*ResultStatus, error) {
// return &ResultStatus{v}, nil
// }
// func Status(v string) (*ResultStatus, error) {
// return &ResultStatus{v}, nil
// }
//
// Now start the server:
//
// mux := http.NewServeMux()
// rpcserver.RegisterRPCFuncs(mux, Routes)
// wm := rpcserver.NewWebsocketManager(Routes)
// mux.HandleFunc("/websocket", wm.WebsocketHandler)
// logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
// listener, err := rpc.Listen("0.0.0.0:8080", rpcserver.Config{})
// if err != nil { panic(err) }
// go rpcserver.Serve(listener, mux, logger)
// mux := http.NewServeMux()
// rpcserver.RegisterRPCFuncs(mux, Routes)
// wm := rpcserver.NewWebsocketManager(Routes)
// mux.HandleFunc("/websocket", wm.WebsocketHandler)
// logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
// listener, err := rpc.Listen("0.0.0.0:8080", rpcserver.Config{})
// if err != nil { panic(err) }
// go rpcserver.Serve(listener, mux, logger)
//
// Note that unix sockets are supported as well (eg. `/path/to/socket` instead of `0.0.0.0:8008`)
// Now see all available endpoints by sending a GET request to `0.0.0.0:8008`.
// Each route is available as a GET request, as a JSONRPCv2 POST request, and via JSONRPCv2 over websockets.
//
// # Examples
// Examples
//
// - [Tendermint](https://github.com/tendermint/tendermint/blob/master/rpc/core/routes.go)
package jsonrpc

View File

@@ -176,7 +176,6 @@ func arrayParamsToArgs(
// array.
//
// Example:
//
// rpcFunc.args = [rpctypes.Context string]
// rpcFunc.argNames = ["arg"]
func jsonParamsToArgs(rpcFunc *RPCFunc, raw []byte) ([]reflect.Value, error) {

View File

@@ -217,7 +217,7 @@ func (resp RPCResponse) String() string {
// From the JSON-RPC 2.0 spec:
//
// If there was an error in detecting the id in the Request object (e.g. Parse
// error/Invalid Request), it MUST be Null.
// error/Invalid Request), it MUST be Null.
func RPCParseError(err error) RPCResponse {
return NewRPCErrorResponse(nil, -32700, "Parse error. Invalid JSON", err.Error())
}
@@ -225,7 +225,7 @@ func RPCParseError(err error) RPCResponse {
// From the JSON-RPC 2.0 spec:
//
// If there was an error in detecting the id in the Request object (e.g. Parse
// error/Invalid Request), it MUST be Null.
// error/Invalid Request), it MUST be Null.
func RPCInvalidRequestError(id jsonrpcid, err error) RPCResponse {
return NewRPCErrorResponse(id, -32600, "Invalid Request", err.Error())
}
@@ -278,11 +278,8 @@ type Context struct {
// RemoteAddr returns the remote address (usually a string "IP:port").
// If neither HTTPReq nor WSConn is set, an empty string is returned.
// HTTP:
//
// http.Request#RemoteAddr
//
// WS:
//
// result of GetRemoteAddr
func (ctx *Context) RemoteAddr() string {
if ctx.HTTPReq != nil {
@@ -296,12 +293,9 @@ func (ctx *Context) RemoteAddr() string {
// Context returns the request's context.
// The returned context is always non-nil; it defaults to the background context.
// HTTP:
//
// The context is canceled when the client's connection closes, the request
// is canceled (with HTTP/2), or when the ServeHTTP method returns.
//
// WS:
//
// The context is canceled when the client's connections closes.
func (ctx *Context) Context() context.Context {
if ctx.HTTPReq != nil {
@@ -314,7 +308,7 @@ func (ctx *Context) Context() context.Context {
//----------------------------------------
// SOCKETS
//
// Determine if its a unix or tcp socket.
// If tcp, must specify the port; `0.0.0.0` will return incorrectly as "unix" since there's no port
// TODO: deprecate

View File

@@ -17,7 +17,7 @@ import (
"github.com/tendermint/tendermint/version"
)
// database key
// database keys
var (
stateKey = []byte("stateKey")
)

View File

@@ -39,9 +39,7 @@ func calcABCIResponsesKey(height int64) []byte {
//----------------------
var (
lastABCIResponseKey = []byte("lastABCIResponseKey")
)
var lastABCIResponseKey = []byte("lastABCIResponseKey")
//go:generate ../scripts/mockery_generate.sh Store

View File

@@ -17,9 +17,9 @@ import (
BlockStore is a simple low level store for blocks.
There are three types of information stored:
- BlockMeta: Meta information about each block
- Block part: Parts of each block, aggregated w/ PartSet
- Commit: The commit part of each block, for gossiping precommit votes
- BlockMeta: Meta information about each block
- Block part: Parts of each block, aggregated w/ PartSet
- Commit: The commit part of each block, for gossiping precommit votes
Currently the precommit signatures are duplicated in the Block parts as
well as the Commit. In the future this may change, perhaps by moving
@@ -325,7 +325,6 @@ func (bs *BlockStore) PruneBlocks(height int64) (uint64, error) {
// SaveBlock persists the given block, blockParts, and seenCommit to the underlying db.
// blockParts: Must be parts of the block
// seenCommit: The +2/3 precommits that were seen which committed at height.
//
// If all the nodes restart after committing a block,
// we need this to reload the precommits to catch-up nodes to the
// most recent height. Otherwise they'd stall at H-1.

View File

@@ -1,4 +1,4 @@
// nolint: gosec
// nolint:gosec
package app
import (

View File

@@ -1,4 +1,4 @@
// nolint: gosec
//nolint: gosec
package main
import (

View File

@@ -1,4 +1,4 @@
// nolint: goconst
//nolint: goconst
package main
import (

View File

@@ -1,4 +1,4 @@
// nolint: gosec
//nolint: gosec
package e2e
import (

View File

@@ -1,4 +1,4 @@
// nolint: gosec
//nolint: gosec
package main
import (

View File

@@ -200,7 +200,7 @@ func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) BlockID {
var nilBytes []byte
// This follows RFC-6962, i.e. `echo -n | sha256sum`
// This follows RFC-6962, i.e. `echo -n ''| sha256sum`
var emptyBytes = []byte{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8,
0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
0x78, 0x52, 0xb8, 0x55}

View File

@@ -227,7 +227,7 @@ func (b *EventBus) PublishEventValidatorSetUpdates(data EventDataValidatorSetUpd
return b.Publish(EventValidatorSetUpdates, data)
}
// -----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
type NopEventBus struct{}
func (NopEventBus) Subscribe(

View File

@@ -4,9 +4,9 @@ import "reflect"
// Go lacks a simple and safe way to see if something is a typed nil.
// See:
// - https://dave.cheney.net/2017/08/09/typed-nils-in-go-2
// - https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I/discussion
// - https://github.com/golang/go/issues/21538
// - https://dave.cheney.net/2017/08/09/typed-nils-in-go-2
// - https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I/discussion
// - https://github.com/golang/go/issues/21538
func isTypedNil(o interface{}) bool {
rv := reflect.ValueOf(o)
switch rv.Kind() {

View File

@@ -411,18 +411,14 @@ func processChanges(origChanges []*Validator) (updates, removals []*Validator, e
//
// Inputs:
// updates - a list of proper validator changes, i.e. they have been verified by processChanges for duplicates
//
// and invalid values.
//
// and invalid values.
// vals - the original validator set. Note that vals is NOT modified by this function.
// removedPower - the total voting power that will be removed after the updates are verified and applied.
//
// Returns:
// tvpAfterUpdatesBeforeRemovals - the new total voting power if these updates would be applied without the removals.
//
// Note that this will be < 2 * MaxTotalVotingPower in case high power validators are removed and
// validators are added/ updated with high power values.
//
// err - non-nil if the maximum allowed total voting power would be exceeded
func verifyUpdates(
updates []*Validator,
@@ -473,7 +469,6 @@ func numNewValidators(updates []*Validator, vals *ValidatorSet) int {
//
// not the removals. It must be < 2*MaxTotalVotingPower and may be close to this limit if close to
// MaxTotalVotingPower will be removed. This is still safe from overflow since MaxTotalVotingPower is maxInt64/8.
//
// No changes are made to the validator set 'vals'.
func computeNewPriorities(updates []*Validator, vals *ValidatorSet, updatedTotalVotingPower int64) {
for _, valUpdate := range updates {
@@ -650,7 +645,6 @@ func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes
// - applies the updates against the validator set
// - applies the removals against the validator set
// - performs scaling and centering of priority values
//
// If an error is detected during verification steps, it is returned and the validator set
// is not changed.
func (vals *ValidatorSet) UpdateWithChangeSet(changes []*Validator) error {

View File

@@ -1641,7 +1641,7 @@ func TestValidatorSetProtoBuf(t *testing.T) {
}
}
// ---------------------
//---------------------
// Sort validators by priority and address
type validatorsByPriority []*Validator
@@ -1682,8 +1682,9 @@ func (tvals testValsByVotingPower) Swap(i, j int) {
tvals[i], tvals[j] = tvals[j], tvals[i]
}
// -------------------------------------
//-------------------------------------
// Benchmark tests
//
func BenchmarkUpdates(b *testing.B) {
const (
n = 100

View File

@@ -25,38 +25,38 @@ const (
type P2PID string
/*
VoteSet helps collect signatures from validators at each height+round for a
predefined vote type.
VoteSet helps collect signatures from validators at each height+round for a
predefined vote type.
We need VoteSet to be able to keep track of conflicting votes when validators
double-sign. Yet, we can't keep track of *all* the votes seen, as that could
be a DoS attack vector.
We need VoteSet to be able to keep track of conflicting votes when validators
double-sign. Yet, we can't keep track of *all* the votes seen, as that could
be a DoS attack vector.
There are two storage areas for votes.
1. voteSet.votes
2. voteSet.votesByBlock
There are two storage areas for votes.
1. voteSet.votes
2. voteSet.votesByBlock
`.votes` is the "canonical" list of votes. It always has at least one vote,
if a vote from a validator had been seen at all. Usually it keeps track of
the first vote seen, but when a 2/3 majority is found, votes for that get
priority and are copied over from `.votesByBlock`.
`.votes` is the "canonical" list of votes. It always has at least one vote,
if a vote from a validator had been seen at all. Usually it keeps track of
the first vote seen, but when a 2/3 majority is found, votes for that get
priority and are copied over from `.votesByBlock`.
`.votesByBlock` keeps track of a list of votes for a particular block. There
are two ways a &blockVotes{} gets created in `.votesByBlock`.
1. the first vote seen by a validator was for the particular block.
2. a peer claims to have seen 2/3 majority for the particular block.
`.votesByBlock` keeps track of a list of votes for a particular block. There
are two ways a &blockVotes{} gets created in `.votesByBlock`.
1. the first vote seen by a validator was for the particular block.
2. a peer claims to have seen 2/3 majority for the particular block..
Since the first vote from a validator will always get added in `.votesByBlock`
, all votes in `.votes` will have a corresponding entry in `.votesByBlock`.
Since the first vote from a validator will always get added in `.votesByBlock`
, all votes in `.votes` will have a corresponding entry in `.votesByBlock`.
When a &blockVotes{} in `.votesByBlock` reaches a 2/3 majority quorum, its
votes are copied into `.votes`.
When a &blockVotes{} in `.votesByBlock` reaches a 2/3 majority quorum, its
votes are copied into `.votes`.
All this is memory bounded because conflicting votes only get added if a peer
told us to track that block, each peer only gets to tell us 1 such block, and,
there's only a limited number of peers.
All this is memory bounded because conflicting votes only get added if a peer
told us to track that block, each peer only gets to tell us 1 such block, and,
there's only a limited number of peers.
NOTE: Assumes that the sum total of voting power does not exceed MaxUInt64.
NOTE: Assumes that the sum total of voting power does not exceed MaxUInt64.
*/
type VoteSet struct {
chainID string
@@ -133,10 +133,8 @@ func (voteSet *VoteSet) Size() int {
// Returns added=true if vote is valid and new.
// Otherwise returns err=ErrVote[
//
// UnexpectedStep | InvalidIndex | InvalidAddress |
// InvalidSignature | InvalidBlockHash | ConflictingVotes ]
//
// UnexpectedStep | InvalidIndex | InvalidAddress |
// InvalidSignature | InvalidBlockHash | ConflictingVotes ]
// Duplicate votes return added=false, err=nil.
// Conflicting votes return added=*, err=ErrVoteConflictingVotes.
// NOTE: vote should not be mutated after adding.
@@ -638,10 +636,10 @@ func (voteSet *VoteSet) MakeCommit() *Commit {
//--------------------------------------------------------------------------------
/*
Votes for a particular block
There are two ways a *blockVotes gets created for a blockKey.
1. first (non-conflicting) vote of a validator w/ blockKey (peerMaj23=false)
2. A peer claims to have a 2/3 majority w/ blockKey (peerMaj23=true)
Votes for a particular block
There are two ways a *blockVotes gets created for a blockKey.
1. first (non-conflicting) vote of a validator w/ blockKey (peerMaj23=false)
2. A peer claims to have a 2/3 majority w/ blockKey (peerMaj23=true)
*/
type blockVotes struct {
peerMaj23 bool // peer claims to have maj23