e2e: Fix hashing for app + Fix logic of TestApp_Hash (#8229)

* Fix hashing of e2e App

* Fix TestApp_Hash

* CaMeL

* Update test/e2e/app/state.go

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>

* for-->Eventually + if-->require

* Update test/e2e/tests/app_test.go

Co-authored-by: Sam Kleinman <garen@tychoish.com>

* fix lint

Co-authored-by: M. J. Fromberger <fromberger@interchain.io>
Co-authored-by: Sam Kleinman <garen@tychoish.com>
This commit is contained in:
Sergio Mena
2022-03-31 22:21:25 +02:00
committed by GitHub
parent b68424be47
commit 4a504c0687
3 changed files with 23 additions and 18 deletions

View File

@@ -92,7 +92,7 @@ func (s *SnapshotStore) Create(state *State) (abci.Snapshot, error) {
snapshot := abci.Snapshot{
Height: state.Height,
Format: 1,
Hash: hashItems(state.Values),
Hash: hashItems(state.Values, state.Height),
Chunks: byteChunks(bz),
}
err = os.WriteFile(filepath.Join(s.dir, fmt.Sprintf("%v.json", state.Height)), bz, 0644)

View File

@@ -3,6 +3,7 @@ package app
import (
"crypto/sha256"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
@@ -38,7 +39,7 @@ func NewState(dir string, persistInterval uint64) (*State, error) {
previousFile: filepath.Join(dir, prevStateFileName),
persistInterval: persistInterval,
}
state.Hash = hashItems(state.Values)
state.Hash = hashItems(state.Values, state.Height)
err := state.load()
switch {
case errors.Is(err, os.ErrNotExist):
@@ -114,7 +115,7 @@ func (s *State) Import(height uint64, jsonBytes []byte) error {
}
s.Height = height
s.Values = values
s.Hash = hashItems(values)
s.Hash = hashItems(values, height)
return s.save()
}
@@ -140,7 +141,6 @@ func (s *State) Set(key, value string) {
func (s *State) Commit() (uint64, []byte, error) {
s.Lock()
defer s.Unlock()
s.Hash = hashItems(s.Values)
switch {
case s.Height > 0:
s.Height++
@@ -149,6 +149,7 @@ func (s *State) Commit() (uint64, []byte, error) {
default:
s.Height = 1
}
s.Hash = hashItems(s.Values, s.Height)
if s.persistInterval > 0 && s.Height%s.persistInterval == 0 {
err := s.save()
if err != nil {
@@ -171,7 +172,7 @@ func (s *State) Rollback() error {
}
// hashItems hashes a set of key/value items.
func hashItems(items map[string]string) []byte {
func hashItems(items map[string]string, height uint64) []byte {
keys := make([]string, 0, len(items))
for key := range items {
keys = append(keys, key)
@@ -179,6 +180,9 @@ func hashItems(items map[string]string) []byte {
sort.Strings(keys)
hasher := sha256.New()
var b [8]byte
binary.BigEndian.PutUint64(b[:], height)
_, _ = hasher.Write(b[:])
for _, key := range keys {
_, _ = hasher.Write([]byte(key))
_, _ = hasher.Write([]byte{0})

View File

@@ -48,23 +48,24 @@ func TestApp_Hash(t *testing.T) {
info, err := client.ABCIInfo(ctx)
require.NoError(t, err)
require.NotEmpty(t, info.Response.LastBlockAppHash, "expected app to return app hash")
// In next-block execution, the app hash is stored in the next block
blockHeight := info.Response.LastBlockHeight + 1
status, err := client.Status(ctx)
require.NoError(t, err)
require.NotZero(t, status.SyncInfo.LatestBlockHeight)
require.Eventually(t, func() bool {
status, err := client.Status(ctx)
require.NoError(t, err)
require.NotZero(t, status.SyncInfo.LatestBlockHeight)
return status.SyncInfo.LatestBlockHeight >= blockHeight
}, 60*time.Second, 500*time.Millisecond)
block, err := client.Block(ctx, &info.Response.LastBlockHeight)
block, err := client.Block(ctx, &blockHeight)
require.NoError(t, err)
if info.Response.LastBlockHeight == block.Block.Height {
require.Equal(t,
fmt.Sprintf("%x", info.Response.LastBlockAppHash),
fmt.Sprintf("%x", block.Block.AppHash.Bytes()),
"app hash does not match last block's app hash")
}
require.True(t, status.SyncInfo.LatestBlockHeight >= info.Response.LastBlockHeight,
"status out of sync with application")
require.Equal(t, blockHeight, block.Block.Height)
require.Equal(t,
fmt.Sprintf("%x", info.Response.LastBlockAppHash),
fmt.Sprintf("%x", block.Block.AppHash.Bytes()),
"app hash does not match last block's app hash")
})
}