2018-02-04 19:54:51 +00:00
|
|
|
package core
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2018-02-06 06:43:32 +00:00
|
|
|
|
2018-03-17 11:53:21 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
2019-09-16 09:33:53 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/io"
|
2018-03-09 15:55:25 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
2019-02-20 17:39:32 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2018-02-04 19:54:51 +00:00
|
|
|
)
|
|
|
|
|
2018-02-06 06:43:32 +00:00
|
|
|
func TestAddHeaders(t *testing.T) {
|
2018-03-17 11:53:21 +00:00
|
|
|
bc := newTestChain(t)
|
2018-03-09 15:55:25 +00:00
|
|
|
h1 := newBlock(1).Header()
|
|
|
|
h2 := newBlock(2).Header()
|
|
|
|
h3 := newBlock(3).Header()
|
2018-02-04 19:54:51 +00:00
|
|
|
|
2018-02-06 06:43:32 +00:00
|
|
|
if err := bc.AddHeaders(h1, h2, h3); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2018-03-09 15:55:25 +00:00
|
|
|
|
|
|
|
assert.Equal(t, h3.Index, bc.HeaderHeight())
|
|
|
|
assert.Equal(t, uint32(0), bc.BlockHeight())
|
|
|
|
assert.Equal(t, h3.Hash(), bc.CurrentHeaderHash())
|
2018-03-10 12:04:06 +00:00
|
|
|
|
|
|
|
// Add them again, they should not be added.
|
|
|
|
if err := bc.AddHeaders(h3, h2, h1); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, h3.Index, bc.HeaderHeight())
|
|
|
|
assert.Equal(t, uint32(0), bc.BlockHeight())
|
|
|
|
assert.Equal(t, h3.Hash(), bc.CurrentHeaderHash())
|
2018-03-09 15:55:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddBlock(t *testing.T) {
|
2018-03-17 11:53:21 +00:00
|
|
|
bc := newTestChain(t)
|
2018-03-09 15:55:25 +00:00
|
|
|
blocks := []*Block{
|
2019-10-10 17:02:09 +00:00
|
|
|
newBlock(1, newMinerTX()),
|
|
|
|
newBlock(2, newMinerTX()),
|
|
|
|
newBlock(3, newMinerTX()),
|
2018-02-06 06:43:32 +00:00
|
|
|
}
|
2018-03-09 15:55:25 +00:00
|
|
|
|
|
|
|
for i := 0; i < len(blocks); i++ {
|
|
|
|
if err := bc.AddBlock(blocks[i]); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lastBlock := blocks[len(blocks)-1]
|
|
|
|
assert.Equal(t, lastBlock.Index, bc.HeaderHeight())
|
|
|
|
assert.Equal(t, lastBlock.Hash(), bc.CurrentHeaderHash())
|
2018-03-25 10:45:54 +00:00
|
|
|
|
2019-09-24 15:51:20 +00:00
|
|
|
// This one tests persisting blocks, so it does need to persist()
|
2019-10-21 07:04:58 +00:00
|
|
|
require.NoError(t, bc.persist())
|
2018-03-09 15:55:25 +00:00
|
|
|
|
2018-03-25 10:45:54 +00:00
|
|
|
for _, block := range blocks {
|
2019-11-27 09:23:18 +00:00
|
|
|
key := storage.AppendPrefix(storage.DataBlock, block.Hash().BytesLE())
|
2019-11-25 17:39:11 +00:00
|
|
|
if _, err := bc.dao.store.Get(key); err != nil {
|
2018-03-25 10:45:54 +00:00
|
|
|
t.Fatalf("block %s not persisted", block.Hash())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-09 15:55:25 +00:00
|
|
|
assert.Equal(t, lastBlock.Index, bc.BlockHeight())
|
|
|
|
assert.Equal(t, lastBlock.Hash(), bc.CurrentHeaderHash())
|
|
|
|
}
|
|
|
|
|
2018-03-17 11:53:21 +00:00
|
|
|
func TestGetHeader(t *testing.T) {
|
|
|
|
bc := newTestChain(t)
|
2019-10-10 17:02:09 +00:00
|
|
|
block := newBlock(1, newMinerTX())
|
2018-03-17 11:53:21 +00:00
|
|
|
err := bc.AddBlock(block)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
2019-09-24 15:51:20 +00:00
|
|
|
// Test unpersisted and persisted access
|
|
|
|
for i := 0; i < 2; i++ {
|
|
|
|
hash := block.Hash()
|
|
|
|
header, err := bc.GetHeader(hash)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, block.Header(), header)
|
|
|
|
|
|
|
|
b2 := newBlock(2)
|
|
|
|
_, err = bc.GetHeader(b2.Hash())
|
|
|
|
assert.Error(t, err)
|
2019-10-21 07:04:58 +00:00
|
|
|
assert.NoError(t, bc.persist())
|
2019-09-24 15:51:20 +00:00
|
|
|
}
|
2018-03-17 11:53:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetBlock(t *testing.T) {
|
|
|
|
bc := newTestChain(t)
|
|
|
|
blocks := makeBlocks(100)
|
|
|
|
|
|
|
|
for i := 0; i < len(blocks); i++ {
|
|
|
|
if err := bc.AddBlock(blocks[i]); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-24 15:51:20 +00:00
|
|
|
// Test unpersisted and persisted access
|
|
|
|
for j := 0; j < 2; j++ {
|
|
|
|
for i := 0; i < len(blocks); i++ {
|
|
|
|
block, err := bc.GetBlock(blocks[i].Hash())
|
|
|
|
if err != nil {
|
2019-10-11 11:24:00 +00:00
|
|
|
t.Fatalf("can't get block %d: %s, attempt %d", i, err, j)
|
2019-09-24 15:51:20 +00:00
|
|
|
}
|
|
|
|
assert.Equal(t, blocks[i].Index, block.Index)
|
|
|
|
assert.Equal(t, blocks[i].Hash(), block.Hash())
|
2018-03-17 11:53:21 +00:00
|
|
|
}
|
2019-10-21 07:04:58 +00:00
|
|
|
assert.NoError(t, bc.persist())
|
2018-03-17 11:53:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHasBlock(t *testing.T) {
|
|
|
|
bc := newTestChain(t)
|
|
|
|
blocks := makeBlocks(50)
|
|
|
|
|
|
|
|
for i := 0; i < len(blocks); i++ {
|
|
|
|
if err := bc.AddBlock(blocks[i]); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-24 15:51:20 +00:00
|
|
|
// Test unpersisted and persisted access
|
|
|
|
for j := 0; j < 2; j++ {
|
|
|
|
for i := 0; i < len(blocks); i++ {
|
|
|
|
assert.True(t, bc.HasBlock(blocks[i].Hash()))
|
|
|
|
}
|
|
|
|
newBlock := newBlock(51)
|
|
|
|
assert.False(t, bc.HasBlock(newBlock.Hash()))
|
2019-10-21 07:04:58 +00:00
|
|
|
assert.NoError(t, bc.persist())
|
2018-03-17 11:53:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-21 16:11:04 +00:00
|
|
|
func TestGetTransaction(t *testing.T) {
|
2019-09-26 15:14:00 +00:00
|
|
|
b1 := getDecodedBlock(t, 1)
|
2019-09-10 20:21:26 +00:00
|
|
|
block := getDecodedBlock(t, 2)
|
2018-03-21 16:11:04 +00:00
|
|
|
bc := newTestChain(t)
|
2019-10-21 08:05:10 +00:00
|
|
|
// Turn verification off, because these blocks are really from some other chain
|
|
|
|
// and can't be verified, but we don't care about that in this test.
|
|
|
|
bc.config.VerifyBlocks = false
|
2018-03-21 16:11:04 +00:00
|
|
|
|
2019-10-21 08:05:10 +00:00
|
|
|
assert.Nil(t, bc.AddBlock(b1))
|
|
|
|
assert.Nil(t, bc.AddBlock(block))
|
2018-03-21 16:11:04 +00:00
|
|
|
|
2019-09-24 15:51:20 +00:00
|
|
|
// Test unpersisted and persisted access
|
|
|
|
for j := 0; j < 2; j++ {
|
|
|
|
tx, height, err := bc.GetTransaction(block.Transactions[0].Hash())
|
|
|
|
require.Nil(t, err)
|
|
|
|
assert.Equal(t, block.Index, height)
|
|
|
|
assert.Equal(t, block.Transactions[0], tx)
|
|
|
|
assert.Equal(t, 10, io.GetVarSize(tx))
|
|
|
|
assert.Equal(t, 1, io.GetVarSize(tx.Attributes))
|
|
|
|
assert.Equal(t, 1, io.GetVarSize(tx.Inputs))
|
|
|
|
assert.Equal(t, 1, io.GetVarSize(tx.Outputs))
|
|
|
|
assert.Equal(t, 1, io.GetVarSize(tx.Scripts))
|
2019-10-21 07:04:58 +00:00
|
|
|
assert.NoError(t, bc.persist())
|
2018-03-21 16:11:04 +00:00
|
|
|
}
|
|
|
|
}
|
2019-11-07 17:47:48 +00:00
|
|
|
|
|
|
|
func TestClose(t *testing.T) {
|
|
|
|
defer func() {
|
|
|
|
r := recover()
|
|
|
|
assert.NotNil(t, r)
|
|
|
|
}()
|
|
|
|
bc := newTestChain(t)
|
|
|
|
blocks := makeBlocks(10)
|
|
|
|
for i := 0; i < len(blocks); i++ {
|
|
|
|
require.NoError(t, bc.AddBlock(blocks[i]))
|
|
|
|
}
|
|
|
|
bc.Close()
|
|
|
|
// It's a hack, but we use internal knowledge of MemoryStore
|
|
|
|
// implementation which makes it completely unusable (up to panicing)
|
|
|
|
// after Close().
|
2019-11-25 17:39:11 +00:00
|
|
|
_ = bc.dao.store.Put([]byte{0}, []byte{1})
|
2019-11-07 17:47:48 +00:00
|
|
|
|
|
|
|
// This should never be executed.
|
|
|
|
assert.Nil(t, t)
|
|
|
|
}
|