types: test tm2pm on fully populated header

This commit is contained in:
Ethan Buchman 2018-10-19 16:55:00 -04:00
parent 9d62bd0ad3
commit c75c7de5a6
5 changed files with 112 additions and 38 deletions

View File

@ -128,7 +128,7 @@ func (state State) IsEmpty() bool {
// MakeBlock builds a block from the current state with the given txs, commit, // MakeBlock builds a block from the current state with the given txs, commit,
// and evidence. Note it also takes a proposerAddress because the state does not // and evidence. Note it also takes a proposerAddress because the state does not
// track rounds, and hence doesn't know the correct proposer. TODO: alleviate this! // track rounds, and hence does not know the correct proposer. TODO: fix this!
func (state State) MakeBlock( func (state State) MakeBlock(
height int64, height int64,
txs []types.Tx, txs []types.Tx,
@ -140,29 +140,22 @@ func (state State) MakeBlock(
// Build base block with block data. // Build base block with block data.
block := types.MakeBlock(height, txs, commit, evidence) block := types.MakeBlock(height, txs, commit, evidence)
// Fill rest of header with state data. // Set time.
block.Version = state.Version.Consensus var timestamp time.Time
block.ChainID = state.ChainID
// Set time
if height == 1 { if height == 1 {
block.Time = state.LastBlockTime // genesis time timestamp = state.LastBlockTime // genesis time
} else { } else {
block.Time = MedianTime(commit, state.LastValidators) timestamp = MedianTime(commit, state.LastValidators)
} }
block.LastBlockID = state.LastBlockID // Fill rest of header with state data.
block.TotalTxs = state.LastBlockTotalTx + block.NumTxs block.Header.Populate(
state.Version.Consensus, state.ChainID,
block.ValidatorsHash = state.Validators.Hash() timestamp, state.LastBlockID, state.LastBlockTotalTx+block.NumTxs,
block.NextValidatorsHash = state.NextValidators.Hash() state.Validators.Hash(), state.NextValidators.Hash(),
block.ConsensusHash = state.ConsensusParams.Hash() state.ConsensusParams.Hash(), state.AppHash, state.LastResultsHash,
block.AppHash = state.AppHash proposerAddress,
block.LastResultsHash = state.LastResultsHash )
// NOTE: we can't use the state.Validators because we don't
// IncrementAccum for rounds there.
block.ProposerAddress = proposerAddress
return block, block.MakePartSet(types.BlockPartSizeBytes) return block, block.MakePartSet(types.BlockPartSizeBytes)
} }

View File

@ -257,11 +257,11 @@ func MaxDataBytesUnknownEvidence(maxBytes int64, valsCount int) int64 {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Header defines the structure of a Tendermint block header // Header defines the structure of a Tendermint block header.
// NOTE: changes to the Header should be duplicated in: // NOTE: changes to the Header should be duplicated in:
// - header.Hash() // - header.Hash()
// - abci.Header // - abci.Header
// - /docs/spec/blockchain/blockchain.md // - /docs/spec/blockchain/blockchain.md
type Header struct { type Header struct {
// basic block info // basic block info
Version version.Consensus `json:"version"` Version version.Consensus `json:"version"`
@ -290,6 +290,41 @@ type Header struct {
ProposerAddress Address `json:"proposer_address"` // original proposer of the block ProposerAddress Address `json:"proposer_address"` // original proposer of the block
} }
func newHeader(
height, numTxs int64,
commitHash, dataHash, evidenceHash []byte,
) *Header {
return &Header{
Height: height,
NumTxs: numTxs,
LastCommitHash: commitHash,
DataHash: dataHash,
EvidenceHash: evidenceHash,
}
}
// Populate the Header with state-derived data.
// Call this after MakeBlock to complete the Header.
func (h *Header) Populate(
version version.Consensus, chainID string,
timestamp time.Time, lastBlockID BlockID, totalTxs int64,
valHash, nextValHash []byte,
consensusHash, appHash, lastResultsHash []byte,
proposerAddress Address,
) {
h.Version = version
h.ChainID = chainID
h.Time = timestamp
h.LastBlockID = lastBlockID
h.TotalTxs = totalTxs
h.ValidatorsHash = valHash
h.NextValidatorsHash = nextValHash
h.ConsensusHash = consensusHash
h.AppHash = appHash
h.LastResultsHash = lastResultsHash
h.ProposerAddress = proposerAddress
}
// Hash returns the hash of the header. // Hash returns the hash of the header.
// It computes a Merkle tree from the header fields // It computes a Merkle tree from the header fields
// ordered as they appear in the Header. // ordered as they appear in the Header.

View File

@ -34,6 +34,10 @@ type tm2pb struct{}
func (tm2pb) Header(header *Header) abci.Header { func (tm2pb) Header(header *Header) abci.Header {
return abci.Header{ return abci.Header{
Version: abci.Version{
Block: header.Version.Block.Uint64(),
App: header.Version.App.Uint64(),
},
ChainID: header.ChainID, ChainID: header.ChainID,
Height: header.Height, Height: header.Height,
Time: header.Time, Time: header.Time,
@ -45,10 +49,11 @@ func (tm2pb) Header(header *Header) abci.Header {
LastCommitHash: header.LastCommitHash, LastCommitHash: header.LastCommitHash,
DataHash: header.DataHash, DataHash: header.DataHash,
ValidatorsHash: header.ValidatorsHash, ValidatorsHash: header.ValidatorsHash,
ConsensusHash: header.ConsensusHash, NextValidatorsHash: header.NextValidatorsHash,
AppHash: header.AppHash, ConsensusHash: header.ConsensusHash,
LastResultsHash: header.LastResultsHash, AppHash: header.AppHash,
LastResultsHash: header.LastResultsHash,
EvidenceHash: header.EvidenceHash, EvidenceHash: header.EvidenceHash,
ProposerAddress: header.ProposerAddress, ProposerAddress: header.ProposerAddress,

View File

@ -4,12 +4,16 @@ import (
"testing" "testing"
"time" "time"
"github.com/golang/protobuf/proto"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/tendermint/go-amino"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/secp256k1" "github.com/tendermint/tendermint/crypto/secp256k1"
tmtime "github.com/tendermint/tendermint/types/time" "github.com/tendermint/tendermint/version"
) )
func TestABCIPubKey(t *testing.T) { func TestABCIPubKey(t *testing.T) {
@ -76,16 +80,53 @@ func TestABCIConsensusParams(t *testing.T) {
} }
func TestABCIHeader(t *testing.T) { func TestABCIHeader(t *testing.T) {
header := &Header{ // build a full header
Height: int64(3), var height int64 = 5
Time: tmtime.Now(), var numTxs int64 = 3
NumTxs: int64(10), header := newHeader(
ProposerAddress: []byte("cloak"), height, numTxs,
[]byte("lastCommitHash"), []byte("dataHash"), []byte("evidenceHash"),
)
protocolVersion := version.Consensus{7, 8}
timestamp := time.Now()
lastBlockID := BlockID{
Hash: []byte("hash"),
PartsHeader: PartSetHeader{
Total: 10,
Hash: []byte("hash"),
},
} }
abciHeader := TM2PB.Header(header) var totalTxs int64 = 100
header.Populate(
protocolVersion, "chainID",
timestamp, lastBlockID, totalTxs,
[]byte("valHash"), []byte("nextValHash"),
[]byte("consHash"), []byte("appHash"), []byte("lastResultsHash"),
[]byte("proposerAddress"),
)
cdc := amino.NewCodec()
headerBz := cdc.MustMarshalBinaryBare(header)
pbHeader := TM2PB.Header(header)
pbHeaderBz, err := proto.Marshal(&pbHeader)
assert.NoError(t, err)
// assert some fields match
assert.EqualValues(t, protocolVersion.Block, pbHeader.Version.Block)
assert.EqualValues(t, protocolVersion.App, pbHeader.Version.App)
assert.EqualValues(t, "chainID", pbHeader.ChainID)
assert.EqualValues(t, height, pbHeader.Height)
assert.EqualValues(t, timestamp, pbHeader.Time)
assert.EqualValues(t, numTxs, pbHeader.NumTxs)
assert.EqualValues(t, totalTxs, pbHeader.TotalTxs)
assert.EqualValues(t, lastBlockID.Hash, pbHeader.LastBlockId.Hash)
assert.EqualValues(t, []byte("lastCommitHash"), pbHeader.LastCommitHash)
assert.Equal(t, []byte("proposerAddress"), pbHeader.ProposerAddress)
// assert the encodings match
assert.EqualValues(t, headerBz, pbHeaderBz)
assert.Equal(t, int64(3), abciHeader.Height)
assert.Equal(t, []byte("cloak"), abciHeader.ProposerAddress)
} }
func TestABCIEvidence(t *testing.T) { func TestABCIEvidence(t *testing.T) {

View File

@ -43,7 +43,7 @@ func TestABCIResults(t *testing.T) {
} }
} }
func TestABCIBytes(t *testing.T) { func TestABCIrResultsBytes(t *testing.T) {
results := NewResults([]*abci.ResponseDeliverTx{ results := NewResults([]*abci.ResponseDeliverTx{
{Code: 0, Data: []byte{}}, {Code: 0, Data: []byte{}},
{Code: 0, Data: []byte("one")}, {Code: 0, Data: []byte("one")},