Add ResultHash to header

This commit is contained in:
Ethan Frey 2017-12-22 16:43:45 +01:00 committed by Ethan Buchman
parent 632cc918b4
commit 58c5df729b
12 changed files with 44 additions and 21 deletions

View File

@ -46,7 +46,7 @@ func TestDynamicCert(t *testing.T) {
for _, tc := range cases {
check := tc.keys.GenCommit(chainID, tc.height, nil, tc.vals,
[]byte("bar"), []byte("params"), tc.first, tc.last)
[]byte("bar"), []byte("params"), []byte("results"), tc.first, tc.last)
err := cert.Certify(check)
if tc.proper {
assert.Nil(err, "%+v", err)
@ -71,7 +71,7 @@ func TestDynamicUpdate(t *testing.T) {
// one valid block to give us a sense of time
h := int64(100)
good := keys.GenCommit(chainID, h, nil, vals, []byte("foo"), []byte("params"), 0, len(keys))
good := keys.GenCommit(chainID, h, nil, vals, []byte("foo"), []byte("params"), []byte("results"), 0, len(keys))
err := cert.Certify(good)
require.Nil(err, "%+v", err)
@ -109,7 +109,7 @@ func TestDynamicUpdate(t *testing.T) {
for _, tc := range cases {
fc := tc.keys.GenFullCommit(chainID, tc.height, nil, tc.vals,
[]byte("bar"), []byte("params"), tc.first, tc.last)
[]byte("bar"), []byte("params"), []byte("results"), tc.first, tc.last)
err := cert.Update(fc)
if tc.proper {
assert.Nil(err, "%d: %+v", tc.height, err)

View File

@ -29,7 +29,7 @@ func TestSerializeFullCommits(t *testing.T) {
// build a fc
keys := lite.GenValKeys(5)
vals := keys.ToValidators(10, 0)
fc := keys.GenFullCommit(chainID, h, nil, vals, appHash, []byte("params"), 0, 5)
fc := keys.GenFullCommit(chainID, h, nil, vals, appHash, []byte("params"), []byte("results"), 0, 5)
require.Equal(h, fc.Height())
require.Equal(vals.Hash(), fc.ValidatorsHash())

View File

@ -46,7 +46,7 @@ func TestFileProvider(t *testing.T) {
// (10, 0), (10, 1), (10, 1), (10, 2), (10, 2), ...
vals := keys.ToValidators(10, int64(count/2))
h := int64(20 + 10*i)
check := keys.GenCommit(chainID, h, nil, vals, appHash, []byte("params"), 0, 5)
check := keys.GenCommit(chainID, h, nil, vals, appHash, []byte("params"), []byte("results"), 0, 5)
seeds[i] = lite.NewFullCommit(check, vals)
}

View File

@ -110,7 +110,7 @@ func makeVote(header *types.Header, vals *types.ValidatorSet, key crypto.PrivKey
// Silences warning that vals can also be merkle.Hashable
// nolint: interfacer
func genHeader(chainID string, height int64, txs types.Txs,
vals *types.ValidatorSet, appHash, consHash []byte) *types.Header {
vals *types.ValidatorSet, appHash, consHash, resHash []byte) *types.Header {
return &types.Header{
ChainID: chainID,
@ -124,14 +124,15 @@ func genHeader(chainID string, height int64, txs types.Txs,
DataHash: txs.Hash(),
AppHash: appHash,
ConsensusHash: consHash,
ResultsHash: resHash,
}
}
// GenCommit calls genHeader and signHeader and combines them into a Commit.
func (v ValKeys) GenCommit(chainID string, height int64, txs types.Txs,
vals *types.ValidatorSet, appHash, consHash []byte, first, last int) Commit {
vals *types.ValidatorSet, appHash, consHash, resHash []byte, first, last int) Commit {
header := genHeader(chainID, height, txs, vals, appHash, consHash)
header := genHeader(chainID, height, txs, vals, appHash, consHash, resHash)
check := Commit{
Header: header,
Commit: v.signHeader(header, first, last),
@ -141,9 +142,9 @@ func (v ValKeys) GenCommit(chainID string, height int64, txs types.Txs,
// GenFullCommit calls genHeader and signHeader and combines them into a Commit.
func (v ValKeys) GenFullCommit(chainID string, height int64, txs types.Txs,
vals *types.ValidatorSet, appHash, consHash []byte, first, last int) FullCommit {
vals *types.ValidatorSet, appHash, consHash, resHash []byte, first, last int) FullCommit {
header := genHeader(chainID, height, txs, vals, appHash, consHash)
header := genHeader(chainID, height, txs, vals, appHash, consHash, resHash)
commit := Commit{
Header: header,
Commit: v.signHeader(header, first, last),

View File

@ -23,6 +23,7 @@ func TestInquirerValidPath(t *testing.T) {
// construct a bunch of commits, each with one more height than the last
chainID := "inquiry-test"
consHash := []byte("params")
resHash := []byte("results")
count := 50
commits := make([]lite.FullCommit, count)
for i := 0; i < count; i++ {
@ -31,7 +32,7 @@ func TestInquirerValidPath(t *testing.T) {
vals := keys.ToValidators(vote, 0)
h := int64(20 + 10*i)
appHash := []byte(fmt.Sprintf("h=%d", h))
commits[i] = keys.GenFullCommit(chainID, h, nil, vals, appHash, consHash, 0, len(keys))
commits[i] = keys.GenFullCommit(chainID, h, nil, vals, appHash, consHash, resHash, 0, len(keys))
}
// initialize a certifier with the initial state
@ -79,7 +80,8 @@ func TestInquirerMinimalPath(t *testing.T) {
vals := keys.ToValidators(vote, 0)
h := int64(5 + 10*i)
appHash := []byte(fmt.Sprintf("h=%d", h))
commits[i] = keys.GenFullCommit(chainID, h, nil, vals, appHash, consHash, 0, len(keys))
resHash := []byte(fmt.Sprintf("res=%d", h))
commits[i] = keys.GenFullCommit(chainID, h, nil, vals, appHash, consHash, resHash, 0, len(keys))
}
// initialize a certifier with the initial state
@ -127,7 +129,8 @@ func TestInquirerVerifyHistorical(t *testing.T) {
vals := keys.ToValidators(vote, 0)
h := int64(20 + 10*i)
appHash := []byte(fmt.Sprintf("h=%d", h))
commits[i] = keys.GenFullCommit(chainID, h, nil, vals, appHash, consHash, 0, len(keys))
resHash := []byte(fmt.Sprintf("res=%d", h))
commits[i] = keys.GenFullCommit(chainID, h, nil, vals, appHash, consHash, resHash, 0, len(keys))
}
// initialize a certifier with the initial state

View File

@ -33,7 +33,8 @@ func benchmarkGenCommit(b *testing.B, keys lite.ValKeys) {
for i := 0; i < b.N; i++ {
h := int64(1 + i)
appHash := []byte(fmt.Sprintf("h=%d", h))
keys.GenCommit(chainID, h, nil, vals, appHash, []byte("params"), 0, len(keys))
resHash := []byte(fmt.Sprintf("res=%d", h))
keys.GenCommit(chainID, h, nil, vals, appHash, []byte("params"), resHash, 0, len(keys))
}
}
@ -105,7 +106,7 @@ func benchmarkCertifyCommit(b *testing.B, keys lite.ValKeys) {
chainID := "bench-certify"
vals := keys.ToValidators(20, 10)
cert := lite.NewStatic(chainID, vals)
check := keys.GenCommit(chainID, 123, nil, vals, []byte("foo"), []byte("params"), 0, len(keys))
check := keys.GenCommit(chainID, 123, nil, vals, []byte("foo"), []byte("params"), []byte("res"), 0, len(keys))
for i := 0; i < b.N; i++ {
err := cert.Certify(check)
if err != nil {

View File

@ -58,7 +58,7 @@ func checkProvider(t *testing.T, p lite.Provider, chainID, app string) {
// (10, 0), (10, 1), (10, 1), (10, 2), (10, 2), ...
vals := keys.ToValidators(10, int64(count/2))
h := int64(20 + 10*i)
commits[i] = keys.GenFullCommit(chainID, h, nil, vals, appHash, []byte("params"), 0, 5)
commits[i] = keys.GenFullCommit(chainID, h, nil, vals, appHash, []byte("params"), []byte("results"), 0, 5)
}
// check provider is empty
@ -129,7 +129,7 @@ func TestCacheGetsBestHeight(t *testing.T) {
for i := 0; i < count; i++ {
vals := keys.ToValidators(10, int64(count/2))
h := int64(10 * (i + 1))
fc := keys.GenFullCommit(chainID, h, nil, vals, appHash, []byte("params"), 0, 5)
fc := keys.GenFullCommit(chainID, h, nil, vals, appHash, []byte("params"), []byte("results"), 0, 5)
err := p2.StoreCommit(fc)
require.NoError(err)
}

View File

@ -44,7 +44,7 @@ func TestStaticCert(t *testing.T) {
for _, tc := range cases {
check := tc.keys.GenCommit(chainID, tc.height, nil, tc.vals,
[]byte("foo"), []byte("params"), tc.first, tc.last)
[]byte("foo"), []byte("params"), []byte("results"), tc.first, tc.last)
err := cert.Certify(check)
if tc.proper {
assert.Nil(err, "%+v", err)

View File

@ -241,6 +241,7 @@ func (s *State) MakeBlock(height int64, txs []types.Tx, commit *types.Commit) (*
block.ValidatorsHash = s.Validators.Hash()
block.AppHash = s.AppHash
block.ConsensusHash = s.LastConsensusParams.Hash()
block.ResultsHash = s.LastResultHash
return block, block.MakePartSet(s.ConsensusParams.BlockGossip.BlockPartSizeBytes)
}
@ -279,6 +280,9 @@ func (s *State) validateBlock(b *types.Block) error {
if !bytes.Equal(b.ConsensusHash, s.LastConsensusParams.Hash()) {
return fmt.Errorf("Wrong Block.Header.ConsensusHash. Expected %X, got %v", s.LastConsensusParams.Hash(), b.ConsensusHash)
}
if !bytes.Equal(b.ResultsHash, s.LastResultHash) {
return fmt.Errorf("Wrong Block.Header.ResultsHash. Expected %X, got %v", s.LastResultHash, b.ResultsHash)
}
// Validate block LastCommit.
if b.Height == 1 {

View File

@ -67,6 +67,12 @@ func TestValidateBlock(t *testing.T) {
block.ConsensusHash = []byte("wrong consensus hash")
err = state.ValidateBlock(block)
require.Error(t, err)
// wrong results hash fails
block = makeBlock(state, 1)
block.ResultsHash = []byte("wrong results hash")
err = state.ValidateBlock(block)
require.Error(t, err)
}
func TestApplyBlock(t *testing.T) {

View File

@ -80,7 +80,8 @@ type State struct {
// Store LastABCIResults along with hash
LastResults ABCIResults // TODO: remove??
LastResultHash []byte
LastResultHash []byte // this is the one for the next block to propose
LastLastResultHash []byte // this verifies the last block?
// The latest AppHash we've received from calling abci.Commit()
AppHash []byte
@ -156,6 +157,9 @@ func (s *State) Copy() *State {
AppHash: s.AppHash,
LastResults: s.LastResults,
LastResultHash: s.LastResultHash,
logger: s.logger,
}
}

View File

@ -153,6 +153,7 @@ type Header struct {
ValidatorsHash data.Bytes `json:"validators_hash"` // validators for the current block
ConsensusHash data.Bytes `json:"consensus_hash"` // consensus params for current block
AppHash data.Bytes `json:"app_hash"` // state after txs from the previous block
ResultsHash data.Bytes `json:"results_hash"` // root hash of all results from the txs from the previous block
}
// Hash returns the hash of the header.
@ -173,6 +174,7 @@ func (h *Header) Hash() data.Bytes {
"Validators": h.ValidatorsHash,
"App": h.AppHash,
"Consensus": h.ConsensusHash,
"Results": h.ResultsHash,
})
}
@ -193,6 +195,7 @@ func (h *Header) StringIndented(indent string) string {
%s Validators: %v
%s App: %v
%s Conensus: %v
%s Results: %v
%s}#%v`,
indent, h.ChainID,
indent, h.Height,
@ -205,6 +208,7 @@ func (h *Header) StringIndented(indent string) string {
indent, h.ValidatorsHash,
indent, h.AppHash,
indent, h.ConsensusHash,
indent, h.ResultsHash,
indent, h.Hash())
}