lightwalletd/common/cache_test.go

185 lines
4.4 KiB
Go

// Copyright (c) 2019-2020 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
package common
import (
"encoding/hex"
"encoding/json"
"io/ioutil"
"os"
"testing"
"github.com/adityapk00/lightwalletd/parser"
"github.com/adityapk00/lightwalletd/walletrpc"
)
var compacts []*walletrpc.CompactBlock
var cache *BlockCache
const (
unitTestPath = "unittestcache"
unitTestChain = "unittestnet"
)
func TestCache(t *testing.T) {
type compactTest struct {
BlockHeight int `json:"block"`
BlockHash string `json:"hash"`
PrevHash string `json:"prev"`
Full string `json:"full"`
Compact string `json:"compact"`
}
var compactTests []compactTest
blockJSON, err := ioutil.ReadFile("../testdata/compact_blocks.json")
if err != nil {
t.Fatal(err)
}
err = json.Unmarshal(blockJSON, &compactTests)
if err != nil {
t.Fatal(err)
}
// Derive compact blocks from file data (setup, not part of the test).
for _, test := range compactTests {
blockData, _ := hex.DecodeString(test.Full)
block := parser.NewBlock()
blockData, err = block.ParseFromSlice(blockData)
if err != nil {
t.Fatal(err)
}
if len(blockData) > 0 {
t.Error("Extra data remaining")
}
compacts = append(compacts, block.ToCompact())
}
// Pretend Sapling starts at 289460.
os.RemoveAll(unitTestPath)
cache = NewBlockCache(unitTestPath, unitTestChain, 289460, 0)
// Initially cache is empty.
if cache.GetLatestHeight() != -1 {
t.Fatal("unexpected GetLatestHeight")
}
if cache.firstBlock != 289460 {
t.Fatal("unexpected initial firstBlock")
}
if cache.nextBlock != 289460 {
t.Fatal("unexpected initial nextBlock")
}
fillCache(t)
reorgCache(t)
fillCache(t)
// Simulate a restart to ensure the db files are read correctly.
cache = NewBlockCache(unitTestPath, unitTestChain, 289460, -1)
// Should still be 6 blocks.
if cache.nextBlock != 289466 {
t.Fatal("unexpected nextBlock height")
}
reorgCache(t)
// Reorg to before the first block moves back to only the first block
cache.Reorg(289459)
if cache.latestHash != nil {
t.Fatal("unexpected latestHash, should be nil")
}
if cache.nextBlock != 289460 {
t.Fatal("unexpected nextBlock: ", cache.nextBlock)
}
// Clean up the test files.
cache.Close()
os.RemoveAll(unitTestPath)
}
func reorgCache(t *testing.T) {
// Simulate a reorg by adding a block whose height is lower than the latest;
// we're replacing the second block, so there should be only two blocks.
cache.Reorg(289461)
err := cache.Add(289461, compacts[1])
if err != nil {
t.Fatal(err)
}
if cache.firstBlock != 289460 {
t.Fatal("unexpected firstBlock height")
}
if cache.nextBlock != 289462 {
t.Fatal("unexpected nextBlock height")
}
if len(cache.starts) != 3 {
t.Fatal("unexpected len(cache.starts)")
}
// some "black-box" tests (using exported interfaces)
if cache.GetLatestHeight() != 289461 {
t.Fatal("unexpected GetLatestHeight")
}
if int(cache.Get(289461).Height) != 289461 {
t.Fatal("unexpected block contents")
}
// Make sure we can go forward from here
err = cache.Add(289462, compacts[2])
if err != nil {
t.Fatal(err)
}
if cache.firstBlock != 289460 {
t.Fatal("unexpected firstBlock height")
}
if cache.nextBlock != 289463 {
t.Fatal("unexpected nextBlock height")
}
if len(cache.starts) != 4 {
t.Fatal("unexpected len(cache.starts)")
}
if cache.GetLatestHeight() != 289462 {
t.Fatal("unexpected GetLatestHeight")
}
if int(cache.Get(289462).Height) != 289462 {
t.Fatal("unexpected block contents")
}
}
// Whatever the state of the cache, add 6 blocks starting at the
// pretend Sapling height, 289460 (this could cause a reorg).
func fillCache(t *testing.T) {
next := 289460
cache.Reorg(next)
for i, compact := range compacts {
err := cache.Add(next, compact)
if err != nil {
t.Fatal(err)
}
next++
// some "white-box" checks
if cache.firstBlock != 289460 {
t.Fatal("unexpected firstBlock height")
}
if cache.nextBlock != 289460+i+1 {
t.Fatal("unexpected nextBlock height")
}
if len(cache.starts) != i+2 {
t.Fatal("unexpected len(cache.starts)")
}
// some "black-box" tests (using exported interfaces)
if cache.GetLatestHeight() != 289460+i {
t.Fatal("unexpected GetLatestHeight")
}
b := cache.Get(289460 + i)
if b == nil {
t.Fatal("unexpected Get failure")
}
if int(b.Height) != 289460+i {
t.Fatal("unexpected block contents")
}
}
}