Skip to content

Commit

Permalink
make BlockTimeIota a consensus parameter, not a locally configurable …
Browse files Browse the repository at this point in the history
…option

Refs #2920
  • Loading branch information
melekes committed Mar 4, 2019
1 parent f39138a commit fa1529e
Show file tree
Hide file tree
Showing 25 changed files with 627 additions and 456 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ protoc_all: protoc_libs protoc_merkle protoc_abci protoc_grpc protoc_proto3types
## See https://stackoverflow.com/a/25518702
## Note the $< here is substituted for the %.proto
## Note the $@ here is substituted for the %.pb.go
protoc $(INCLUDE) $< --gogo_out=Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,plugins=grpc:.
protoc $(INCLUDE) $< --gogo_out=Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration,plugins=grpc:.

########################################
### Build ABCI
Expand Down
679 changes: 368 additions & 311 deletions abci/types/types.pb.go

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions abci/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ package types;
// For more information on gogo.proto, see:
// https://github.com/gogo/protobuf/blob/master/extensions.md
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "github.com/tendermint/tendermint/libs/common/types.proto";
import "github.com/tendermint/tendermint/crypto/merkle/merkle.proto";
import "github.com/tendermint/tendermint/libs/common/types.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

// This file is copied from http://github.com/tendermint/abci
// NOTE: When using custom types, mind the warnings.
Expand Down Expand Up @@ -207,17 +208,19 @@ message ResponseCommit {
// ConsensusParams contains all consensus-relevant parameters
// that can be adjusted by the abci app
message ConsensusParams {
BlockSizeParams block_size = 1;
BlockParams block = 1;
EvidenceParams evidence = 2;
ValidatorParams validator = 3;
}

// BlockSize contains limits on the block size.
message BlockSizeParams {
// BlockParams contains limits on the block size.
message BlockParams {
// Note: must be greater than 0
int64 max_bytes = 1;
// Note: must be greater or equal to -1
int64 max_gas = 2;
// Note: must be greater or equal to 0
google.protobuf.Duration time_iota = 3 [(gogoproto.nullable)=false, (gogoproto.stdduration)=true];
}

// EvidenceParams contains limits on the evidence.
Expand Down
35 changes: 18 additions & 17 deletions abci/types/typespb_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 0 additions & 14 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -613,9 +613,6 @@ type ConsensusConfig struct {
// Reactor sleep duration parameters
PeerGossipSleepDuration time.Duration `mapstructure:"peer_gossip_sleep_duration"`
PeerQueryMaj23SleepDuration time.Duration `mapstructure:"peer_query_maj23_sleep_duration"`

// Block time parameters. Corresponds to the minimum time increment between consecutive blocks.
BlockTimeIota time.Duration `mapstructure:"blocktime_iota"`
}

// DefaultConsensusConfig returns a default configuration for the consensus service
Expand All @@ -634,7 +631,6 @@ func DefaultConsensusConfig() *ConsensusConfig {
CreateEmptyBlocksInterval: 0 * time.Second,
PeerGossipSleepDuration: 100 * time.Millisecond,
PeerQueryMaj23SleepDuration: 2000 * time.Millisecond,
BlockTimeIota: 1000 * time.Millisecond,
}
}

Expand All @@ -651,16 +647,9 @@ func TestConsensusConfig() *ConsensusConfig {
cfg.SkipTimeoutCommit = true
cfg.PeerGossipSleepDuration = 5 * time.Millisecond
cfg.PeerQueryMaj23SleepDuration = 250 * time.Millisecond
cfg.BlockTimeIota = 10 * time.Millisecond
return cfg
}

// MinValidVoteTime returns the minimum acceptable block time.
// See the [BFT time spec](https://godoc.org/github.com/tendermint/tendermint/docs/spec/consensus/bft-time.md).
func (cfg *ConsensusConfig) MinValidVoteTime(lastBlockTime time.Time) time.Time {
return lastBlockTime.Add(cfg.BlockTimeIota)
}

// WaitForTxs returns true if the consensus should wait for transactions before entering the propose step
func (cfg *ConsensusConfig) WaitForTxs() bool {
return !cfg.CreateEmptyBlocks || cfg.CreateEmptyBlocksInterval > 0
Expand Down Expand Up @@ -738,9 +727,6 @@ func (cfg *ConsensusConfig) ValidateBasic() error {
if cfg.PeerQueryMaj23SleepDuration < 0 {
return errors.New("peer_query_maj23_sleep_duration can't be negative")
}
if cfg.BlockTimeIota < 0 {
return errors.New("blocktime_iota can't be negative")
}
return nil
}

Expand Down
3 changes: 0 additions & 3 deletions config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,6 @@ create_empty_blocks_interval = "{{ .Consensus.CreateEmptyBlocksInterval }}"
peer_gossip_sleep_duration = "{{ .Consensus.PeerGossipSleepDuration }}"
peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}"
# Block time parameters. Corresponds to the minimum time increment between consecutive blocks.
blocktime_iota = "{{ .Consensus.BlockTimeIota }}"
##### transactions indexer configuration options #####
[tx_index]
Expand Down
7 changes: 4 additions & 3 deletions consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,7 @@ func (cs *ConsensusState) addProposalBlockPart(msg *BlockPartMessage, peerID p2p
_, err = cdc.UnmarshalBinaryLengthPrefixedReader(
cs.ProposalBlockParts.GetReader(),
&cs.ProposalBlock,
int64(cs.state.ConsensusParams.BlockSize.MaxBytes),
int64(cs.state.ConsensusParams.Block.MaxBytes),
)
if err != nil {
return added, err
Expand Down Expand Up @@ -1702,9 +1702,10 @@ func (cs *ConsensusState) voteTime() time.Time {
// TODO: We should remove next line in case we don't vote for v in case cs.ProposalBlock == nil,
// even if cs.LockedBlock != nil. See https://github.com/tendermint/spec.
if cs.LockedBlock != nil {
minVoteTime = cs.config.MinValidVoteTime(cs.LockedBlock.Time)
// See the BFT time spec https://tendermint.com/docs/spec/consensus/bft-time.html
minVoteTime = cs.LockedBlock.Time.Add(cs.state.ConsensusParams.Block.TimeIota.Duration)
} else if cs.ProposalBlock != nil {
minVoteTime = cs.config.MinValidVoteTime(cs.ProposalBlock.Time)
minVoteTime = cs.ProposalBlock.Time.Add(cs.state.ConsensusParams.Block.TimeIota.Duration)
}

if now.After(minVoteTime) {
Expand Down
6 changes: 4 additions & 2 deletions docs/spec/abci/abci.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,19 +443,21 @@ Commit are included in the header of the next block.
### ConsensusParams

- **Fields**:
- `BlockSize (BlockSizeParams)`: Parameters limiting the size of a block.
- `Block (BlockParams)`: Parameters limiting the size of a block and time between consecutive blocks.
- `Evidence (EvidenceParams)`: Parameters limiting the validity of
evidence of byzantine behaviour.
- `Validator (ValidatorParams)`: Parameters limitng the types of pubkeys validators can use.

### BlockSizeParams
### BlockParams

- **Fields**:
- `MaxBytes (int64)`: Max size of a block, in bytes.
- `MaxGas (int64)`: Max sum of `GasWanted` in a proposed block.
- NOTE: blocks that violate this may be committed if there are Byzantine proposers.
It's the application's responsibility to handle this when processing a
block!
- `TimeIota (google.protobuf.Duration)`: Minimum time increment between consecutive blocks.


### EvidenceParams

Expand Down
17 changes: 12 additions & 5 deletions docs/spec/abci/apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ the difference credited back. Tendermint adopts a similar abstraction,
though uses it only optionally and weakly, allowing applications to define
their own sense of the cost of execution.

In Tendermint, the `ConsensusParams.BlockSize.MaxGas` limits the amount of `gas` that can be used in a block.
In Tendermint, the `ConsensusParams.Block.MaxGas` limits the amount of `gas` that can be used in a block.
The default value is `-1`, meaning no limit, or that the concept of gas is
meaningless.

Expand Down Expand Up @@ -225,7 +225,7 @@ ConsensusParams enforce certain limits in the blockchain, like the maximum size
of blocks, amount of gas used in a block, and the maximum acceptable age of
evidence. They can be set in InitChain and updated in EndBlock.

### BlockSize.MaxBytes
### Block.MaxBytes

The maximum size of a complete Amino encoded block.
This is enforced by Tendermint consensus.
Expand All @@ -235,7 +235,7 @@ the header, the validator set, and any included evidence in the block.

Must have `0 < MaxBytes < 100 MB`.

### BlockSize.MaxGas
### Block.MaxGas

The maximum of the sum of `GasWanted` in a proposed block.
This is *not* enforced by Tendermint consensus.
Expand All @@ -246,6 +246,13 @@ txs included in a proposed block.
Must have `MaxGas >= -1`.
If `MaxGas == -1`, no limit is enforced.

### Block.TimeIota

The minimum time between consecutive blocks.
This is enforced by Tendermint consensus.

Must have `TimeIota >= 0`.

### EvidenceParams.MaxAge

This is the maximum age of evidence.
Expand All @@ -260,8 +267,8 @@ Must have `0 < MaxAge`.
The application may set the ConsensusParams during InitChain, and update them during
EndBlock. If the ConsensusParams is empty, it will be ignored. Each field
that is not empty will be applied in full. For instance, if updating the
BlockSize.MaxBytes, applications must also set the other BlockSize fields (like
BlockSize.MaxGas), even if they are unchanged, as they will otherwise cause the
Block.MaxBytes, applications must also set the other Block fields (like
Block.MaxGas), even if they are unchanged, as they will otherwise cause the
value to be updated to 0.

#### InitChain
Expand Down
22 changes: 11 additions & 11 deletions docs/spec/blockchain/state.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ evolve without breaking the header.

```go
type ConsensusParams struct {
BlockSize
Block
Evidence
Validator
}
Expand All @@ -95,38 +95,38 @@ type hashedParams struct {

func (params ConsensusParams) Hash() []byte {
SHA256(hashedParams{
BlockMaxBytes: params.BlockSize.MaxBytes,
BlockMaxGas: params.BlockSize.MaxGas,
BlockMaxBytes: params.Block.MaxBytes,
BlockMaxGas: params.Block.MaxGas,
})
}

type BlockSize struct {
type BlockParams struct {
MaxBytes int64
MaxGas int64
TimeIota time.Duration
}

type Evidence struct {
type EvidenceParams struct {
MaxAge int64
}

type Validator struct {
PubKeyTypes []string
}

type ValidatorParams struct {
PubKeyTypes []string
}
```

#### BlockSize
#### Block

The total size of a block is limited in bytes by the `ConsensusParams.BlockSize.MaxBytes`.
The total size of a block is limited in bytes by the `ConsensusParams.Block.MaxBytes`.
Proposed blocks must be less than this size, and will be considered invalid
otherwise.

Blocks should additionally be limited by the amount of "gas" consumed by the
transactions in the block, though this is not yet implemented.

The minimal time between consecutive blocks is controlled by the
`ConsensusParams.Block.TimeIota`.

#### Evidence

For evidence in a block to be valid, it must satisfy:
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/consensus/creating-proposal.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A block consists of a header, transactions, votes (the commit),
and a list of evidence of malfeasance (ie. signing conflicting votes).

We include no more than 1/10th of the maximum block size
(`ConsensusParams.BlockSize.MaxBytes`) of evidence with each block.
(`ConsensusParams.Block.MaxBytes`) of evidence with each block.

## Reaping transactions from the mempool

Expand Down
2 changes: 1 addition & 1 deletion node/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ func TestCreateProposalBlock(t *testing.T) {
var height int64 = 1
state, stateDB := state(1, height)
maxBytes := 16384
state.ConsensusParams.BlockSize.MaxBytes = int64(maxBytes)
state.ConsensusParams.Block.MaxBytes = int64(maxBytes)
proposerAddr, _ := state.Validators.GetByIndex(0)

// Make Mempool
Expand Down
4 changes: 2 additions & 2 deletions state/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ func (blockExec *BlockExecutor) CreateProposalBlock(
proposerAddr []byte,
) (*types.Block, *types.PartSet) {

maxBytes := state.ConsensusParams.BlockSize.MaxBytes
maxGas := state.ConsensusParams.BlockSize.MaxGas
maxBytes := state.ConsensusParams.Block.MaxBytes
maxGas := state.ConsensusParams.Block.MaxGas

// Fetch a limited amount of valid evidence
maxNumEvidence, _ := types.MaxEvidencePerBlock(maxBytes)
Expand Down

0 comments on commit fa1529e

Please sign in to comment.