You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

413 lines
12 KiB

add missing Timestamp to Votes Fixes: ``` panic: Panicked on a Sanity Check: can't encode times below 1970 [recovered] panic: Panicked on a Sanity Check: can't encode times below 1970 goroutine 2042 [running]: testing.tRunner.func1(0xc420e8c0f0) /usr/local/go/src/testing/testing.go:711 +0x5d9 panic(0xcd9e20, 0xc420c8c270) /usr/local/go/src/runtime/panic.go:491 +0x2a2 github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.PanicSanity(0xcd9e20, 0xf8ddd0) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/errors.go:26 +0x120 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.WriteTime(0x0, 0x0, 0x0, 0x1306440, 0xc4201607e0, 0xc420e31658, 0xc420e31680) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/time.go:19 +0x11e github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xdc9e40, 0xc4201fcf30, 0x199, 0x1317b80, 0xdc9e40, 0xc98451, 0x9, 0x0, 0xdc9e40, 0xc420ead9c0, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:525 +0x22f0 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xd25400, 0xc42000e2e8, 0x196, 0x1317b80, 0xd92d60, 0xc9a195, 0xa, 0x0, 0xcc8ce0, 0xc420164920, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:530 +0x21e7 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xcc8ce0, 0xc4209f95b8, 0x197, 0x1317b80, 0xcc8ce0, 0xc9a195, 0xa, 0x0, 0xcc8ce0, 0xc420164920, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:518 +0x2509 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xd873e0, 0xc4209f9580, 0x16, 0x1317b80, 0xd79400, 0x0, 0x0, 0x0, 0x0, 0x0, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:530 +0x21e7 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.WriteBinary(0xd873e0, 0xc4209f9580, 0x1306440, 0xc4201607e0, 0xc420e31658, 0xc420e31680) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/wire.go:80 +0x15f github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.BinaryBytes(0xd873e0, 0xc4209f9580, 0x3, 0x8, 0xc420160798) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/util.go:15 +0xb8 github.com/tendermint/tendermint/blockchain.(*BlockStore).SaveBlock(0xc4201342a0, 0xc420eac180, 0xc420130640, 0xc4209f9580) github.com/tendermint/tendermint/blockchain/_test/_obj_test/store.go:192 +0x439 github.com/tendermint/tendermint/blockchain.TestBlockStoreSaveLoadBlock(0xc420e8c0f0) /go/src/github.com/tendermint/tendermint/blockchain/store_test.go:128 +0x609 testing.tRunner(0xc420e8c0f0, 0xf20830) /usr/local/go/src/testing/testing.go:746 +0x16d created by testing.(*T).Run /usr/local/go/src/testing/testing.go:789 +0x569 exit status 2 FAIL ```
7 years ago
add missing Timestamp to Votes Fixes: ``` panic: Panicked on a Sanity Check: can't encode times below 1970 [recovered] panic: Panicked on a Sanity Check: can't encode times below 1970 goroutine 2042 [running]: testing.tRunner.func1(0xc420e8c0f0) /usr/local/go/src/testing/testing.go:711 +0x5d9 panic(0xcd9e20, 0xc420c8c270) /usr/local/go/src/runtime/panic.go:491 +0x2a2 github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.PanicSanity(0xcd9e20, 0xf8ddd0) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/errors.go:26 +0x120 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.WriteTime(0x0, 0x0, 0x0, 0x1306440, 0xc4201607e0, 0xc420e31658, 0xc420e31680) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/time.go:19 +0x11e github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xdc9e40, 0xc4201fcf30, 0x199, 0x1317b80, 0xdc9e40, 0xc98451, 0x9, 0x0, 0xdc9e40, 0xc420ead9c0, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:525 +0x22f0 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xd25400, 0xc42000e2e8, 0x196, 0x1317b80, 0xd92d60, 0xc9a195, 0xa, 0x0, 0xcc8ce0, 0xc420164920, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:530 +0x21e7 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xcc8ce0, 0xc4209f95b8, 0x197, 0x1317b80, 0xcc8ce0, 0xc9a195, 0xa, 0x0, 0xcc8ce0, 0xc420164920, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:518 +0x2509 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xd873e0, 0xc4209f9580, 0x16, 0x1317b80, 0xd79400, 0x0, 0x0, 0x0, 0x0, 0x0, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:530 +0x21e7 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.WriteBinary(0xd873e0, 0xc4209f9580, 0x1306440, 0xc4201607e0, 0xc420e31658, 0xc420e31680) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/wire.go:80 +0x15f github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.BinaryBytes(0xd873e0, 0xc4209f9580, 0x3, 0x8, 0xc420160798) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/util.go:15 +0xb8 github.com/tendermint/tendermint/blockchain.(*BlockStore).SaveBlock(0xc4201342a0, 0xc420eac180, 0xc420130640, 0xc4209f9580) github.com/tendermint/tendermint/blockchain/_test/_obj_test/store.go:192 +0x439 github.com/tendermint/tendermint/blockchain.TestBlockStoreSaveLoadBlock(0xc420e8c0f0) /go/src/github.com/tendermint/tendermint/blockchain/store_test.go:128 +0x609 testing.tRunner(0xc420e8c0f0, 0xf20830) /usr/local/go/src/testing/testing.go:746 +0x16d created by testing.(*T).Run /usr/local/go/src/testing/testing.go:789 +0x569 exit status 2 FAIL ```
7 years ago
add missing Timestamp to Votes Fixes: ``` panic: Panicked on a Sanity Check: can't encode times below 1970 [recovered] panic: Panicked on a Sanity Check: can't encode times below 1970 goroutine 2042 [running]: testing.tRunner.func1(0xc420e8c0f0) /usr/local/go/src/testing/testing.go:711 +0x5d9 panic(0xcd9e20, 0xc420c8c270) /usr/local/go/src/runtime/panic.go:491 +0x2a2 github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.PanicSanity(0xcd9e20, 0xf8ddd0) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/errors.go:26 +0x120 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.WriteTime(0x0, 0x0, 0x0, 0x1306440, 0xc4201607e0, 0xc420e31658, 0xc420e31680) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/time.go:19 +0x11e github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xdc9e40, 0xc4201fcf30, 0x199, 0x1317b80, 0xdc9e40, 0xc98451, 0x9, 0x0, 0xdc9e40, 0xc420ead9c0, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:525 +0x22f0 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xd25400, 0xc42000e2e8, 0x196, 0x1317b80, 0xd92d60, 0xc9a195, 0xa, 0x0, 0xcc8ce0, 0xc420164920, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:530 +0x21e7 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xcc8ce0, 0xc4209f95b8, 0x197, 0x1317b80, 0xcc8ce0, 0xc9a195, 0xa, 0x0, 0xcc8ce0, 0xc420164920, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:518 +0x2509 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xd873e0, 0xc4209f9580, 0x16, 0x1317b80, 0xd79400, 0x0, 0x0, 0x0, 0x0, 0x0, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:530 +0x21e7 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.WriteBinary(0xd873e0, 0xc4209f9580, 0x1306440, 0xc4201607e0, 0xc420e31658, 0xc420e31680) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/wire.go:80 +0x15f github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.BinaryBytes(0xd873e0, 0xc4209f9580, 0x3, 0x8, 0xc420160798) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/util.go:15 +0xb8 github.com/tendermint/tendermint/blockchain.(*BlockStore).SaveBlock(0xc4201342a0, 0xc420eac180, 0xc420130640, 0xc4209f9580) github.com/tendermint/tendermint/blockchain/_test/_obj_test/store.go:192 +0x439 github.com/tendermint/tendermint/blockchain.TestBlockStoreSaveLoadBlock(0xc420e8c0f0) /go/src/github.com/tendermint/tendermint/blockchain/store_test.go:128 +0x609 testing.tRunner(0xc420e8c0f0, 0xf20830) /usr/local/go/src/testing/testing.go:746 +0x16d created by testing.(*T).Run /usr/local/go/src/testing/testing.go:789 +0x569 exit status 2 FAIL ```
7 years ago
add missing Timestamp to Votes Fixes: ``` panic: Panicked on a Sanity Check: can't encode times below 1970 [recovered] panic: Panicked on a Sanity Check: can't encode times below 1970 goroutine 2042 [running]: testing.tRunner.func1(0xc420e8c0f0) /usr/local/go/src/testing/testing.go:711 +0x5d9 panic(0xcd9e20, 0xc420c8c270) /usr/local/go/src/runtime/panic.go:491 +0x2a2 github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.PanicSanity(0xcd9e20, 0xf8ddd0) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/errors.go:26 +0x120 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.WriteTime(0x0, 0x0, 0x0, 0x1306440, 0xc4201607e0, 0xc420e31658, 0xc420e31680) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/time.go:19 +0x11e github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xdc9e40, 0xc4201fcf30, 0x199, 0x1317b80, 0xdc9e40, 0xc98451, 0x9, 0x0, 0xdc9e40, 0xc420ead9c0, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:525 +0x22f0 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xd25400, 0xc42000e2e8, 0x196, 0x1317b80, 0xd92d60, 0xc9a195, 0xa, 0x0, 0xcc8ce0, 0xc420164920, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:530 +0x21e7 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xcc8ce0, 0xc4209f95b8, 0x197, 0x1317b80, 0xcc8ce0, 0xc9a195, 0xa, 0x0, 0xcc8ce0, 0xc420164920, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:518 +0x2509 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xd873e0, 0xc4209f9580, 0x16, 0x1317b80, 0xd79400, 0x0, 0x0, 0x0, 0x0, 0x0, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:530 +0x21e7 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.WriteBinary(0xd873e0, 0xc4209f9580, 0x1306440, 0xc4201607e0, 0xc420e31658, 0xc420e31680) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/wire.go:80 +0x15f github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.BinaryBytes(0xd873e0, 0xc4209f9580, 0x3, 0x8, 0xc420160798) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/util.go:15 +0xb8 github.com/tendermint/tendermint/blockchain.(*BlockStore).SaveBlock(0xc4201342a0, 0xc420eac180, 0xc420130640, 0xc4209f9580) github.com/tendermint/tendermint/blockchain/_test/_obj_test/store.go:192 +0x439 github.com/tendermint/tendermint/blockchain.TestBlockStoreSaveLoadBlock(0xc420e8c0f0) /go/src/github.com/tendermint/tendermint/blockchain/store_test.go:128 +0x609 testing.tRunner(0xc420e8c0f0, 0xf20830) /usr/local/go/src/testing/testing.go:746 +0x16d created by testing.(*T).Run /usr/local/go/src/testing/testing.go:789 +0x569 exit status 2 FAIL ```
7 years ago
add missing Timestamp to Votes Fixes: ``` panic: Panicked on a Sanity Check: can't encode times below 1970 [recovered] panic: Panicked on a Sanity Check: can't encode times below 1970 goroutine 2042 [running]: testing.tRunner.func1(0xc420e8c0f0) /usr/local/go/src/testing/testing.go:711 +0x5d9 panic(0xcd9e20, 0xc420c8c270) /usr/local/go/src/runtime/panic.go:491 +0x2a2 github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common.PanicSanity(0xcd9e20, 0xf8ddd0) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/tmlibs/common/errors.go:26 +0x120 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.WriteTime(0x0, 0x0, 0x0, 0x1306440, 0xc4201607e0, 0xc420e31658, 0xc420e31680) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/time.go:19 +0x11e github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xdc9e40, 0xc4201fcf30, 0x199, 0x1317b80, 0xdc9e40, 0xc98451, 0x9, 0x0, 0xdc9e40, 0xc420ead9c0, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:525 +0x22f0 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xd25400, 0xc42000e2e8, 0x196, 0x1317b80, 0xd92d60, 0xc9a195, 0xa, 0x0, 0xcc8ce0, 0xc420164920, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:530 +0x21e7 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xcc8ce0, 0xc4209f95b8, 0x197, 0x1317b80, 0xcc8ce0, 0xc9a195, 0xa, 0x0, 0xcc8ce0, 0xc420164920, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:518 +0x2509 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.writeReflectBinary(0xd873e0, 0xc4209f9580, 0x16, 0x1317b80, 0xd79400, 0x0, 0x0, 0x0, 0x0, 0x0, ...) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/reflect.go:530 +0x21e7 github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.WriteBinary(0xd873e0, 0xc4209f9580, 0x1306440, 0xc4201607e0, 0xc420e31658, 0xc420e31680) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/wire.go:80 +0x15f github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire.BinaryBytes(0xd873e0, 0xc4209f9580, 0x3, 0x8, 0xc420160798) /go/src/github.com/tendermint/tendermint/vendor/github.com/tendermint/go-wire/util.go:15 +0xb8 github.com/tendermint/tendermint/blockchain.(*BlockStore).SaveBlock(0xc4201342a0, 0xc420eac180, 0xc420130640, 0xc4209f9580) github.com/tendermint/tendermint/blockchain/_test/_obj_test/store.go:192 +0x439 github.com/tendermint/tendermint/blockchain.TestBlockStoreSaveLoadBlock(0xc420e8c0f0) /go/src/github.com/tendermint/tendermint/blockchain/store_test.go:128 +0x609 testing.tRunner(0xc420e8c0f0, 0xf20830) /usr/local/go/src/testing/testing.go:746 +0x16d created by testing.(*T).Run /usr/local/go/src/testing/testing.go:789 +0x569 exit status 2 FAIL ```
7 years ago
  1. package blockchain
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io/ioutil"
  6. "runtime/debug"
  7. "strings"
  8. "testing"
  9. "time"
  10. "github.com/stretchr/testify/assert"
  11. "github.com/stretchr/testify/require"
  12. wire "github.com/tendermint/go-wire"
  13. "github.com/tendermint/tendermint/types"
  14. "github.com/tendermint/tmlibs/db"
  15. "github.com/tendermint/tmlibs/log"
  16. )
  17. func TestLoadBlockStoreStateJSON(t *testing.T) {
  18. db := db.NewMemDB()
  19. bsj := &BlockStoreStateJSON{Height: 1000}
  20. bsj.Save(db)
  21. retrBSJ := LoadBlockStoreStateJSON(db)
  22. assert.Equal(t, *bsj, retrBSJ, "expected the retrieved DBs to match")
  23. }
  24. func TestNewBlockStore(t *testing.T) {
  25. db := db.NewMemDB()
  26. db.Set(blockStoreKey, []byte(`{"height": 10000}`))
  27. bs := NewBlockStore(db)
  28. assert.Equal(t, bs.Height(), int64(10000), "failed to properly parse blockstore")
  29. panicCausers := []struct {
  30. data []byte
  31. wantErr string
  32. }{
  33. {[]byte("artful-doger"), "not unmarshal bytes"},
  34. {[]byte(""), "unmarshal bytes"},
  35. {[]byte(" "), "unmarshal bytes"},
  36. }
  37. for i, tt := range panicCausers {
  38. // Expecting a panic here on trying to parse an invalid blockStore
  39. _, _, panicErr := doFn(func() (interface{}, error) {
  40. db.Set(blockStoreKey, tt.data)
  41. _ = NewBlockStore(db)
  42. return nil, nil
  43. })
  44. require.NotNil(t, panicErr, "#%d panicCauser: %q expected a panic", i, tt.data)
  45. assert.Contains(t, panicErr.Error(), tt.wantErr, "#%d data: %q", i, tt.data)
  46. }
  47. db.Set(blockStoreKey, nil)
  48. bs = NewBlockStore(db)
  49. assert.Equal(t, bs.Height(), int64(0), "expecting nil bytes to be unmarshaled alright")
  50. }
  51. func TestBlockStoreGetReader(t *testing.T) {
  52. db := db.NewMemDB()
  53. // Initial setup
  54. db.Set([]byte("Foo"), []byte("Bar"))
  55. db.Set([]byte("Foo1"), nil)
  56. bs := NewBlockStore(db)
  57. tests := [...]struct {
  58. key []byte
  59. want []byte
  60. }{
  61. 0: {key: []byte("Foo"), want: []byte("Bar")},
  62. 1: {key: []byte("KnoxNonExistent"), want: nil},
  63. 2: {key: []byte("Foo1"), want: nil},
  64. }
  65. for i, tt := range tests {
  66. r := bs.GetReader(tt.key)
  67. if r == nil {
  68. assert.Nil(t, tt.want, "#%d: expected a non-nil reader", i)
  69. continue
  70. }
  71. slurp, err := ioutil.ReadAll(r)
  72. if err != nil {
  73. t.Errorf("#%d: unexpected Read err: %v", i, err)
  74. } else {
  75. assert.Equal(t, slurp, tt.want, "#%d: mismatch", i)
  76. }
  77. }
  78. }
  79. func freshBlockStore() (*BlockStore, db.DB) {
  80. db := db.NewMemDB()
  81. return NewBlockStore(db), db
  82. }
  83. var (
  84. state, _ = makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer)))
  85. block = makeBlock(1, state)
  86. partSet = block.MakePartSet(2)
  87. part1 = partSet.GetPart(0)
  88. part2 = partSet.GetPart(1)
  89. seenCommit1 = &types.Commit{Precommits: []*types.Vote{{Height: 10, Timestamp: time.Now().UTC()}}}
  90. )
  91. // TODO: This test should be simplified ...
  92. func TestBlockStoreSaveLoadBlock(t *testing.T) {
  93. state, bs := makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer)))
  94. require.Equal(t, bs.Height(), int64(0), "initially the height should be zero")
  95. // check there are no blocks at various heights
  96. noBlockHeights := []int64{0, -1, 100, 1000, 2}
  97. for i, height := range noBlockHeights {
  98. if g := bs.LoadBlock(height); g != nil {
  99. t.Errorf("#%d: height(%d) got a block; want nil", i, height)
  100. }
  101. }
  102. // save a block
  103. block := makeBlock(bs.Height()+1, state)
  104. validPartSet := block.MakePartSet(2)
  105. seenCommit := &types.Commit{Precommits: []*types.Vote{{Height: 10, Timestamp: time.Now().UTC()}}}
  106. bs.SaveBlock(block, partSet, seenCommit)
  107. require.Equal(t, bs.Height(), block.Header.Height, "expecting the new height to be changed")
  108. incompletePartSet := types.NewPartSetFromHeader(types.PartSetHeader{Total: 2})
  109. uncontiguousPartSet := types.NewPartSetFromHeader(types.PartSetHeader{Total: 0})
  110. uncontiguousPartSet.AddPart(part2, false)
  111. header1 := types.Header{
  112. Height: 1,
  113. NumTxs: 100,
  114. ChainID: "block_test",
  115. Time: time.Now(),
  116. }
  117. header2 := header1
  118. header2.Height = 4
  119. // End of setup, test data
  120. commitAtH10 := &types.Commit{Precommits: []*types.Vote{{Height: 10, Timestamp: time.Now().UTC()}}}
  121. tuples := []struct {
  122. block *types.Block
  123. parts *types.PartSet
  124. seenCommit *types.Commit
  125. wantErr bool
  126. wantPanic string
  127. corruptBlockInDB bool
  128. corruptCommitInDB bool
  129. corruptSeenCommitInDB bool
  130. eraseCommitInDB bool
  131. eraseSeenCommitInDB bool
  132. }{
  133. {
  134. block: newBlock(&header1, commitAtH10),
  135. parts: validPartSet,
  136. seenCommit: seenCommit1,
  137. },
  138. {
  139. block: nil,
  140. wantPanic: "only save a non-nil block",
  141. },
  142. {
  143. block: newBlock(&header2, commitAtH10),
  144. parts: uncontiguousPartSet,
  145. wantPanic: "only save contiguous blocks", // and incomplete and uncontiguous parts
  146. },
  147. {
  148. block: newBlock(&header1, commitAtH10),
  149. parts: incompletePartSet,
  150. wantPanic: "only save complete block", // incomplete parts
  151. },
  152. {
  153. block: newBlock(&header1, commitAtH10),
  154. parts: validPartSet,
  155. seenCommit: seenCommit1,
  156. corruptCommitInDB: true, // Corrupt the DB's commit entry
  157. wantPanic: "rror reading commit",
  158. },
  159. {
  160. block: newBlock(&header1, commitAtH10),
  161. parts: validPartSet,
  162. seenCommit: seenCommit1,
  163. wantPanic: "rror reading block",
  164. corruptBlockInDB: true, // Corrupt the DB's block entry
  165. },
  166. {
  167. block: newBlock(&header1, commitAtH10),
  168. parts: validPartSet,
  169. seenCommit: seenCommit1,
  170. // Expecting no error and we want a nil back
  171. eraseSeenCommitInDB: true,
  172. },
  173. {
  174. block: newBlock(&header1, commitAtH10),
  175. parts: validPartSet,
  176. seenCommit: seenCommit1,
  177. corruptSeenCommitInDB: true,
  178. wantPanic: "rror reading commit",
  179. },
  180. {
  181. block: newBlock(&header1, commitAtH10),
  182. parts: validPartSet,
  183. seenCommit: seenCommit1,
  184. // Expecting no error and we want a nil back
  185. eraseCommitInDB: true,
  186. },
  187. }
  188. type quad struct {
  189. block *types.Block
  190. commit *types.Commit
  191. meta *types.BlockMeta
  192. seenCommit *types.Commit
  193. }
  194. for i, tuple := range tuples {
  195. bs, db := freshBlockStore()
  196. // SaveBlock
  197. res, err, panicErr := doFn(func() (interface{}, error) {
  198. bs.SaveBlock(tuple.block, tuple.parts, tuple.seenCommit)
  199. if tuple.block == nil {
  200. return nil, nil
  201. }
  202. if tuple.corruptBlockInDB {
  203. db.Set(calcBlockMetaKey(tuple.block.Height), []byte("block-bogus"))
  204. }
  205. bBlock := bs.LoadBlock(tuple.block.Height)
  206. bBlockMeta := bs.LoadBlockMeta(tuple.block.Height)
  207. if tuple.eraseSeenCommitInDB {
  208. db.Delete(calcSeenCommitKey(tuple.block.Height))
  209. }
  210. if tuple.corruptSeenCommitInDB {
  211. db.Set(calcSeenCommitKey(tuple.block.Height), []byte("bogus-seen-commit"))
  212. }
  213. bSeenCommit := bs.LoadSeenCommit(tuple.block.Height)
  214. commitHeight := tuple.block.Height - 1
  215. if tuple.eraseCommitInDB {
  216. db.Delete(calcBlockCommitKey(commitHeight))
  217. }
  218. if tuple.corruptCommitInDB {
  219. db.Set(calcBlockCommitKey(commitHeight), []byte("foo-bogus"))
  220. }
  221. bCommit := bs.LoadBlockCommit(commitHeight)
  222. return &quad{block: bBlock, seenCommit: bSeenCommit, commit: bCommit, meta: bBlockMeta}, nil
  223. })
  224. if subStr := tuple.wantPanic; subStr != "" {
  225. if panicErr == nil {
  226. t.Errorf("#%d: want a non-nil panic", i)
  227. } else if got := panicErr.Error(); !strings.Contains(got, subStr) {
  228. t.Errorf("#%d:\n\tgotErr: %q\nwant substring: %q", i, got, subStr)
  229. }
  230. continue
  231. }
  232. if tuple.wantErr {
  233. if err == nil {
  234. t.Errorf("#%d: got nil error", i)
  235. }
  236. continue
  237. }
  238. assert.Nil(t, panicErr, "#%d: unexpected panic", i)
  239. assert.Nil(t, err, "#%d: expecting a non-nil error", i)
  240. qua, ok := res.(*quad)
  241. if !ok || qua == nil {
  242. t.Errorf("#%d: got nil quad back; gotType=%T", i, res)
  243. continue
  244. }
  245. if tuple.eraseSeenCommitInDB {
  246. assert.Nil(t, qua.seenCommit, "erased the seenCommit in the DB hence we should get back a nil seenCommit")
  247. }
  248. if tuple.eraseCommitInDB {
  249. assert.Nil(t, qua.commit, "erased the commit in the DB hence we should get back a nil commit")
  250. }
  251. }
  252. }
  253. func binarySerializeIt(v interface{}) []byte {
  254. var n int
  255. var err error
  256. buf := new(bytes.Buffer)
  257. wire.WriteBinary(v, buf, &n, &err)
  258. return buf.Bytes()
  259. }
  260. func TestLoadBlockPart(t *testing.T) {
  261. bs, db := freshBlockStore()
  262. height, index := int64(10), 1
  263. loadPart := func() (interface{}, error) {
  264. part := bs.LoadBlockPart(height, index)
  265. return part, nil
  266. }
  267. // Initially no contents.
  268. // 1. Requesting for a non-existent block shouldn't fail
  269. res, _, panicErr := doFn(loadPart)
  270. require.Nil(t, panicErr, "a non-existent block part shouldn't cause a panic")
  271. require.Nil(t, res, "a non-existent block part should return nil")
  272. // 2. Next save a corrupted block then try to load it
  273. db.Set(calcBlockPartKey(height, index), []byte("Tendermint"))
  274. res, _, panicErr = doFn(loadPart)
  275. require.NotNil(t, panicErr, "expecting a non-nil panic")
  276. require.Contains(t, panicErr.Error(), "Error reading block part")
  277. // 3. A good block serialized and saved to the DB should be retrievable
  278. db.Set(calcBlockPartKey(height, index), binarySerializeIt(part1))
  279. gotPart, _, panicErr := doFn(loadPart)
  280. require.Nil(t, panicErr, "an existent and proper block should not panic")
  281. require.Nil(t, res, "a properly saved block should return a proper block")
  282. require.Equal(t, gotPart.(*types.Part).Hash(), part1.Hash(), "expecting successful retrieval of previously saved block")
  283. }
  284. func TestLoadBlockMeta(t *testing.T) {
  285. bs, db := freshBlockStore()
  286. height := int64(10)
  287. loadMeta := func() (interface{}, error) {
  288. meta := bs.LoadBlockMeta(height)
  289. return meta, nil
  290. }
  291. // Initially no contents.
  292. // 1. Requesting for a non-existent blockMeta shouldn't fail
  293. res, _, panicErr := doFn(loadMeta)
  294. require.Nil(t, panicErr, "a non-existent blockMeta shouldn't cause a panic")
  295. require.Nil(t, res, "a non-existent blockMeta should return nil")
  296. // 2. Next save a corrupted blockMeta then try to load it
  297. db.Set(calcBlockMetaKey(height), []byte("Tendermint-Meta"))
  298. res, _, panicErr = doFn(loadMeta)
  299. require.NotNil(t, panicErr, "expecting a non-nil panic")
  300. require.Contains(t, panicErr.Error(), "Error reading block meta")
  301. // 3. A good blockMeta serialized and saved to the DB should be retrievable
  302. meta := &types.BlockMeta{}
  303. db.Set(calcBlockMetaKey(height), binarySerializeIt(meta))
  304. gotMeta, _, panicErr := doFn(loadMeta)
  305. require.Nil(t, panicErr, "an existent and proper block should not panic")
  306. require.Nil(t, res, "a properly saved blockMeta should return a proper blocMeta ")
  307. require.Equal(t, binarySerializeIt(meta), binarySerializeIt(gotMeta), "expecting successful retrieval of previously saved blockMeta")
  308. }
  309. func TestBlockFetchAtHeight(t *testing.T) {
  310. state, bs := makeStateAndBlockStore(log.NewTMLogger(new(bytes.Buffer)))
  311. require.Equal(t, bs.Height(), int64(0), "initially the height should be zero")
  312. block := makeBlock(bs.Height()+1, state)
  313. partSet := block.MakePartSet(2)
  314. seenCommit := &types.Commit{Precommits: []*types.Vote{{Height: 10, Timestamp: time.Now().UTC()}}}
  315. bs.SaveBlock(block, partSet, seenCommit)
  316. require.Equal(t, bs.Height(), block.Header.Height, "expecting the new height to be changed")
  317. blockAtHeight := bs.LoadBlock(bs.Height())
  318. require.Equal(t, block.Hash(), blockAtHeight.Hash(), "expecting a successful load of the last saved block")
  319. blockAtHeightPlus1 := bs.LoadBlock(bs.Height() + 1)
  320. require.Nil(t, blockAtHeightPlus1, "expecting an unsuccessful load of Height()+1")
  321. blockAtHeightPlus2 := bs.LoadBlock(bs.Height() + 2)
  322. require.Nil(t, blockAtHeightPlus2, "expecting an unsuccessful load of Height()+2")
  323. }
  324. func doFn(fn func() (interface{}, error)) (res interface{}, err error, panicErr error) {
  325. defer func() {
  326. if r := recover(); r != nil {
  327. switch e := r.(type) {
  328. case error:
  329. panicErr = e
  330. case string:
  331. panicErr = fmt.Errorf("%s", e)
  332. default:
  333. if st, ok := r.(fmt.Stringer); ok {
  334. panicErr = fmt.Errorf("%s", st)
  335. } else {
  336. panicErr = fmt.Errorf("%s", debug.Stack())
  337. }
  338. }
  339. }
  340. }()
  341. res, err = fn()
  342. return res, err, panicErr
  343. }
  344. func newBlock(hdr *types.Header, lastCommit *types.Commit) *types.Block {
  345. return &types.Block{
  346. Header: hdr,
  347. LastCommit: lastCommit,
  348. }
  349. }