状态包含的信息,其加密摘要会被纳入区块头,因此在验证新区块时是必需的。例如,验证者集合和交易结果本身从不会包含在区块中,但它们的 Merkle 根会包含在内:状态会跟踪这些内容。 State 对象本身属于实现细节,因为它既不会被包含在区块中,也不会通过网络在节点间传播,而且我们从不计算它的哈希。State 对象的持久化或查询接口也属于实现细节,不包含在本规范中。不过,State 对象中的类型属于规范的一部分,因为 State 对象的 Merkle 根会被包含在区块中,并且其中的值会在验证期间使用。
type State struct {
    ChainID        string
    InitialHeight  int64

    LastBlockHeight int64
    LastBlockID     types.BlockID
    LastBlockTime   time.Time

    Version     Version
    LastResults []Result
    AppHash     []byte

    LastValidators ValidatorSet
    Validators     ValidatorSet
    NextValidators ValidatorSet

    ConsensusParams ConsensusParams
}
链 ID 和初始高度取自创世文件,之后不会再次变更。通常情况下,初始高度为 1,0 是无效值。 请注意,验证者数量存在一个硬编码上限,即 10000。这个限制继承自提交中投票数量的上限。 关于 Validator、ValidatorSet 和 ConsensusParams 的更多信息,可参见数据结构。

执行

状态会在区块执行结束时更新。其中尤其需要关注 ResponseEndBlock 和 ResponseCommit。
type ResponseEndBlock struct {
	ValidatorUpdates      []ValidatorUpdate       `protobuf:"bytes,1,rep,name=validator_updates,json=validatorUpdates,proto3" json:"validator_updates"`
	ConsensusParamUpdates *types1.ConsensusParams `protobuf:"bytes,2,opt,name=consensus_param_updates,json=consensusParamUpdates,proto3" json:"consensus_param_updates,omitempty"`
	Events                []Event                 `protobuf:"bytes,3,rep,name=events,proto3" json:"events,omitempty"`
}
其中
type ValidatorUpdate struct {
	PubKey crypto.PublicKey `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key"`
	Power  int64            `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"`
}
以及
type ResponseCommit struct {
	// reserve 1
	Data         []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
	RetainHeight int64  `protobuf:"varint,3,opt,name=retain_height,json=retainHeight,proto3" json:"retain_height,omitempty"`
}
ValidatorUpdates 用于向当前集合中添加和移除验证者,以及更新验证者的投票权重。将 ValidatorUpdate 中的验证者权重设为 0,会导致该验证者被移除。ConsensusParams 会以安全方式复制更新内容(即某个字段为 nil 时会被忽略),而 ResponseCommit 中的 Data 会用作 AppHash。

版本

type Version struct {
  consensus Consensus
  software string
}
Consensus 包含区块链和应用程序的协议版本。

区块

区块总大小的字节上限由 ConsensusParams.Block.MaxBytes 决定。提议的区块必须小于该大小,否则会被视为无效。 应用程序可以将 ConsensusParams.Block.MaxBytes 设置为 -1。 在这种情况下,实际区块上限会被设置为 100 MB, 并且 CometBFT 会在 PrepareProposal 中提供内存池里的全部交易。 应用程序必须谨慎,确保在 ResponsePrepareProposal 中返回的交易列表大小小于或等于 RequestPrepareProposal.MaxTxBytes。 此外,区块还应受到区块内交易所消耗“gas”总量的限制,不过这一点尚未实现。

证据

要使区块中的证据有效,必须满足:
block.Header.Time-evidence.Time < ConsensusParams.Evidence.MaxAgeDuration &&
 block.Header.Height-evidence.Height < ConsensusParams.Evidence.MaxAgeNumBlocks
一个区块中包含的证据总量不得超过 ConsensusParams.Evidence.MaxBytes。这样实现是为了缓解垃圾攻击。

验证者

来自创世文件和 ResponseEndBlock 的验证者,其公钥类型必须属于 ConsensusParams.Validator.PubKeyTypes。
The state contains information whose cryptographic digest is included in block headers, and thus is necessary for validating new blocks. For instance, the validators set and the results of transactions are never included in blocks, but their Merkle roots are: the state keeps track of them. The State object itself is an implementation detail, since it is never included in a block or gossiped over the network, and we never compute its hash. The persistence or query interface of the State object is an implementation detail and not included in the specification. However, the types in the State object are part of the specification, since the Merkle roots of the State objects are included in blocks and values are used during validation.
type State struct {
    ChainID        string
    InitialHeight  int64

    LastBlockHeight int64
    LastBlockID     types.BlockID
    LastBlockTime   time.Time

    Version     Version
    LastResults []Result
    AppHash     []byte

    LastValidators ValidatorSet
    Validators     ValidatorSet
    NextValidators ValidatorSet

    ConsensusParams ConsensusParams
}
The chain ID and initial height are taken from the genesis file, and not changed again. The initial height will be 1 in the typical case, 0 is an invalid value. Note there is a hard-coded limit of 10000 validators. This is inherited from the limit on the number of votes in a commit. Further information on Validator’s, ValidatorSet’s and ConsensusParams’s can be found in data structures

Execution

State gets updated at the end of executing a block. Of specific interest is ResponseEndBlock and ResponseCommit
type ResponseEndBlock struct {
	ValidatorUpdates      []ValidatorUpdate       `protobuf:"bytes,1,rep,name=validator_updates,json=validatorUpdates,proto3" json:"validator_updates"`
	ConsensusParamUpdates *types1.ConsensusParams `protobuf:"bytes,2,opt,name=consensus_param_updates,json=consensusParamUpdates,proto3" json:"consensus_param_updates,omitempty"`
	Events                []Event                 `protobuf:"bytes,3,rep,name=events,proto3" json:"events,omitempty"`
}
where
type ValidatorUpdate struct {
	PubKey crypto.PublicKey `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key"`
	Power  int64            `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"`
}
and
type ResponseCommit struct {
	// reserve 1
	Data         []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
	RetainHeight int64  `protobuf:"varint,3,opt,name=retain_height,json=retainHeight,proto3" json:"retain_height,omitempty"`
}
ValidatorUpdates are used to add and remove validators to the current set as well as update validator power. Setting validator power to 0 in ValidatorUpdate will cause the validator to be removed. ConsensusParams are safely copied across (i.e. if a field is nil it gets ignored) and the Data from the ResponseCommit is used as the AppHash

Version

type Version struct {
  consensus Consensus
  software string
}
Consensus contains the protocol version for the blockchain and the application.

Block

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. The Application may set ConsensusParams.Block.MaxBytes to -1. In that case, the actual block limit is set to 100 MB, and CometBFT will provide all transactions in the mempool as part of PrepareProposal. The application has to be careful to return a list of transactions in ResponsePrepareProposal whose size is less than or equal to RequestPrepareProposal.MaxTxBytes. Blocks should additionally be limited by the amount of “gas” consumed by the transactions in the block, though this is not yet implemented.

Evidence

For evidence in a block to be valid, it must satisfy:
block.Header.Time-evidence.Time < ConsensusParams.Evidence.MaxAgeDuration &&
 block.Header.Height-evidence.Height < ConsensusParams.Evidence.MaxAgeNumBlocks
A block must not contain more than ConsensusParams.Evidence.MaxBytes of evidence. This is implemented to mitigate spam attacks.

Validator

Validators from genesis file and ResponseEndBlock must have pubkeys of type ∈ ConsensusParams.Validator.PubKeyTypes.