core: make unpersisted blocks/txs available in Blockchain

This changes the Blockchain to also return unpersisted (theoretically, verified
in the AddBlock!) blocks and transactions, making Add/Get interfaces
symmetrical. It allows to turn Persist into internal method again and makes it
possible to enable transaction check in GetBlock(), thus fixing #366.
This commit is contained in:
Roman Khimov 2019-09-24 18:51:20 +03:00
parent 2daff0957a
commit 578ac414d4
4 changed files with 125 additions and 59 deletions

View file

@ -63,9 +63,8 @@ func TestAddBlock(t *testing.T) {
t.Log(bc.blockCache)
if err := bc.Persist(context.Background()); err != nil {
t.Fatal(err)
}
// This one tests persisting blocks, so it does need to persist()
require.NoError(t, bc.persist(context.Background()))
for _, block := range blocks {
key := storage.AppendPrefix(storage.DataBlock, block.Hash().BytesReverse())
@ -88,14 +87,18 @@ func TestGetHeader(t *testing.T) {
err := bc.AddBlock(block)
assert.Nil(t, err)
hash := block.Hash()
header, err := bc.GetHeader(hash)
require.NoError(t, err)
assert.Equal(t, block.Header(), header)
// 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)
block = newBlock(2)
_, err = bc.GetHeader(block.Hash())
assert.Error(t, err)
b2 := newBlock(2)
_, err = bc.GetHeader(b2.Hash())
assert.Error(t, err)
assert.NoError(t, bc.persist(context.Background()))
}
}
func TestGetBlock(t *testing.T) {
@ -111,13 +114,17 @@ func TestGetBlock(t *testing.T) {
}
}
for i := 0; i < len(blocks); i++ {
block, err := bc.GetBlock(blocks[i].Hash())
if err != nil {
t.Fatal(err)
// 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 {
t.Fatal(err)
}
assert.Equal(t, blocks[i].Index, block.Index)
assert.Equal(t, blocks[i].Hash(), block.Hash())
}
assert.Equal(t, blocks[i].Index, block.Index)
assert.Equal(t, blocks[i].Hash(), block.Hash())
assert.NoError(t, bc.persist(context.Background()))
}
}
@ -133,14 +140,16 @@ func TestHasBlock(t *testing.T) {
t.Fatal(err)
}
}
assert.Nil(t, bc.Persist(context.Background()))
for i := 0; i < len(blocks); i++ {
assert.True(t, bc.HasBlock(blocks[i].Hash()))
// 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()))
assert.NoError(t, bc.persist(context.Background()))
}
newBlock := newBlock(51)
assert.False(t, bc.HasBlock(newBlock.Hash()))
}
func TestGetTransaction(t *testing.T) {
@ -151,19 +160,20 @@ func TestGetTransaction(t *testing.T) {
}()
assert.Nil(t, bc.AddBlock(block))
assert.Nil(t, bc.persistBlock(block))
tx, height, err := bc.GetTransaction(block.Transactions[0].Hash())
if err != nil {
t.Fatal(err)
// 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))
assert.NoError(t, bc.persist(context.Background()))
}
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))
}
func newTestChain(t *testing.T) *Blockchain {