c258adb532
prevHash == input.PrevHash, so make less DB accesses and more real work. Fix some bugs along the way: * spentCoins structure may already be present in the DB when persisting TX, there is nothing wrong with that and we shouldn't overwrite it * it's only used for NEO and only to check for claim validity. Thus, when processing claim tx the corresponding spentCoins should always be present in the DB
328 lines
9.7 KiB
Go
328 lines
9.7 KiB
Go
package core
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/CityOfZion/neo-go/pkg/core/block"
|
|
"github.com/CityOfZion/neo-go/pkg/core/state"
|
|
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
|
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
|
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
|
|
"github.com/CityOfZion/neo-go/pkg/internal/random"
|
|
"github.com/CityOfZion/neo-go/pkg/io"
|
|
"github.com/CityOfZion/neo-go/pkg/smartcontract"
|
|
"github.com/CityOfZion/neo-go/pkg/vm/opcode"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestPutGetAndDecode(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
serializable := &TestSerializable{field: random.String(4)}
|
|
hash := []byte{1}
|
|
err := dao.Put(serializable, hash)
|
|
require.NoError(t, err)
|
|
|
|
gotAndDecoded := &TestSerializable{}
|
|
err = dao.GetAndDecode(gotAndDecoded, hash)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// TestSerializable structure used in testing.
|
|
type TestSerializable struct {
|
|
field string
|
|
}
|
|
|
|
func (t *TestSerializable) EncodeBinary(writer *io.BinWriter) {
|
|
writer.WriteString(t.field)
|
|
}
|
|
|
|
func (t *TestSerializable) DecodeBinary(reader *io.BinReader) {
|
|
t.field = reader.ReadString()
|
|
}
|
|
|
|
func TestGetAccountStateOrNew_New(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint160()
|
|
createdAccount, err := dao.GetAccountStateOrNew(hash)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, createdAccount)
|
|
}
|
|
|
|
func TestPutAndGetAccountStateOrNew(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint160()
|
|
accountState := &state.Account{ScriptHash: hash}
|
|
err := dao.PutAccountState(accountState)
|
|
require.NoError(t, err)
|
|
gotAccount, err := dao.GetAccountStateOrNew(hash)
|
|
require.NoError(t, err)
|
|
require.Equal(t, accountState.ScriptHash, gotAccount.ScriptHash)
|
|
}
|
|
|
|
func TestPutAndGetAssetState(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
id := random.Uint256()
|
|
assetState := &state.Asset{ID: id, Owner: keys.PublicKey{}}
|
|
err := dao.PutAssetState(assetState)
|
|
require.NoError(t, err)
|
|
gotAssetState, err := dao.GetAssetState(id)
|
|
require.NoError(t, err)
|
|
require.Equal(t, assetState, gotAssetState)
|
|
}
|
|
|
|
func TestPutAndGetContractState(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
contractState := &state.Contract{Script: []byte{}, ParamList: []smartcontract.ParamType{}}
|
|
hash := contractState.ScriptHash()
|
|
err := dao.PutContractState(contractState)
|
|
require.NoError(t, err)
|
|
gotContractState, err := dao.GetContractState(hash)
|
|
require.NoError(t, err)
|
|
require.Equal(t, contractState, gotContractState)
|
|
}
|
|
|
|
func TestDeleteContractState(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
contractState := &state.Contract{Script: []byte{}, ParamList: []smartcontract.ParamType{}}
|
|
hash := contractState.ScriptHash()
|
|
err := dao.PutContractState(contractState)
|
|
require.NoError(t, err)
|
|
err = dao.DeleteContractState(hash)
|
|
require.NoError(t, err)
|
|
gotContractState, err := dao.GetContractState(hash)
|
|
require.Error(t, err)
|
|
require.Nil(t, gotContractState)
|
|
}
|
|
|
|
func TestGetUnspentCoinStateOrNew_New(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint256()
|
|
unspentCoinState, err := dao.GetUnspentCoinStateOrNew(hash)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, unspentCoinState)
|
|
}
|
|
|
|
func TestGetUnspentCoinState_Err(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint256()
|
|
gotUnspentCoinState, err := dao.GetUnspentCoinState(hash)
|
|
require.Error(t, err)
|
|
require.Nil(t, gotUnspentCoinState)
|
|
}
|
|
|
|
func TestPutGetUnspentCoinState(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint256()
|
|
unspentCoinState := &UnspentCoinState{states: []state.Coin{}}
|
|
err := dao.PutUnspentCoinState(hash, unspentCoinState)
|
|
require.NoError(t, err)
|
|
gotUnspentCoinState, err := dao.GetUnspentCoinState(hash)
|
|
require.NoError(t, err)
|
|
require.Equal(t, unspentCoinState, gotUnspentCoinState)
|
|
}
|
|
|
|
func TestGetSpentCoinStateOrNew_New(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint256()
|
|
spentCoinState, err := dao.GetSpentCoinsOrNew(hash, 1)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, spentCoinState)
|
|
}
|
|
|
|
func TestPutAndGetSpentCoinState(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint256()
|
|
spentCoinState := &SpentCoinState{items: make(map[uint16]uint32)}
|
|
err := dao.PutSpentCoinState(hash, spentCoinState)
|
|
require.NoError(t, err)
|
|
gotSpentCoinState, err := dao.GetSpentCoinState(hash)
|
|
require.NoError(t, err)
|
|
require.Equal(t, spentCoinState, gotSpentCoinState)
|
|
}
|
|
|
|
func TestGetSpentCoinState_Err(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint256()
|
|
spentCoinState, err := dao.GetSpentCoinState(hash)
|
|
require.Error(t, err)
|
|
require.Nil(t, spentCoinState)
|
|
}
|
|
|
|
func TestDeleteSpentCoinState(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint256()
|
|
spentCoinState := &SpentCoinState{items: make(map[uint16]uint32)}
|
|
err := dao.PutSpentCoinState(hash, spentCoinState)
|
|
require.NoError(t, err)
|
|
err = dao.DeleteSpentCoinState(hash)
|
|
require.NoError(t, err)
|
|
gotSpentCoinState, err := dao.GetSpentCoinState(hash)
|
|
require.Error(t, err)
|
|
require.Nil(t, gotSpentCoinState)
|
|
}
|
|
|
|
func TestGetValidatorStateOrNew_New(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
publicKey := &keys.PublicKey{}
|
|
validatorState, err := dao.GetValidatorStateOrNew(publicKey)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, validatorState)
|
|
}
|
|
|
|
func TestPutGetValidatorState(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
publicKey := &keys.PublicKey{}
|
|
validatorState := &state.Validator{
|
|
PublicKey: publicKey,
|
|
Registered: false,
|
|
Votes: 0,
|
|
}
|
|
err := dao.PutValidatorState(validatorState)
|
|
require.NoError(t, err)
|
|
gotValidatorState, err := dao.GetValidatorState(publicKey)
|
|
require.NoError(t, err)
|
|
require.Equal(t, validatorState, gotValidatorState)
|
|
}
|
|
|
|
func TestDeleteValidatorState(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
publicKey := &keys.PublicKey{}
|
|
validatorState := &state.Validator{
|
|
PublicKey: publicKey,
|
|
Registered: false,
|
|
Votes: 0,
|
|
}
|
|
err := dao.PutValidatorState(validatorState)
|
|
require.NoError(t, err)
|
|
err = dao.DeleteValidatorState(validatorState)
|
|
require.NoError(t, err)
|
|
gotValidatorState, err := dao.GetValidatorState(publicKey)
|
|
require.Error(t, err)
|
|
require.Nil(t, gotValidatorState)
|
|
}
|
|
|
|
func TestGetValidators(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
publicKey := &keys.PublicKey{}
|
|
validatorState := &state.Validator{
|
|
PublicKey: publicKey,
|
|
Registered: false,
|
|
Votes: 0,
|
|
}
|
|
err := dao.PutValidatorState(validatorState)
|
|
require.NoError(t, err)
|
|
validators := dao.GetValidators()
|
|
require.Equal(t, validatorState, validators[0])
|
|
require.Len(t, validators, 1)
|
|
}
|
|
|
|
func TestPutGetAppExecResult(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint256()
|
|
appExecResult := &state.AppExecResult{TxHash: hash, Events: []state.NotificationEvent{}}
|
|
err := dao.PutAppExecResult(appExecResult)
|
|
require.NoError(t, err)
|
|
gotAppExecResult, err := dao.GetAppExecResult(hash)
|
|
require.NoError(t, err)
|
|
require.Equal(t, appExecResult, gotAppExecResult)
|
|
}
|
|
|
|
func TestPutGetStorageItem(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint160()
|
|
key := []byte{0}
|
|
storageItem := &state.StorageItem{Value: []uint8{}}
|
|
err := dao.PutStorageItem(hash, key, storageItem)
|
|
require.NoError(t, err)
|
|
gotStorageItem := dao.GetStorageItem(hash, key)
|
|
require.Equal(t, storageItem, gotStorageItem)
|
|
}
|
|
|
|
func TestDeleteStorageItem(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint160()
|
|
key := []byte{0}
|
|
storageItem := &state.StorageItem{Value: []uint8{}}
|
|
err := dao.PutStorageItem(hash, key, storageItem)
|
|
require.NoError(t, err)
|
|
err = dao.DeleteStorageItem(hash, key)
|
|
require.NoError(t, err)
|
|
gotStorageItem := dao.GetStorageItem(hash, key)
|
|
require.Nil(t, gotStorageItem)
|
|
}
|
|
|
|
func TestGetBlock_NotExists(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
hash := random.Uint256()
|
|
block, err := dao.GetBlock(hash)
|
|
require.Error(t, err)
|
|
require.Nil(t, block)
|
|
}
|
|
|
|
func TestPutGetBlock(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
b := &block.Block{
|
|
Base: block.Base{
|
|
Script: transaction.Witness{
|
|
VerificationScript: []byte{byte(opcode.PUSH1)},
|
|
InvocationScript: []byte{byte(opcode.NOP)},
|
|
},
|
|
},
|
|
}
|
|
hash := b.Hash()
|
|
err := dao.StoreAsBlock(b, 0)
|
|
require.NoError(t, err)
|
|
gotBlock, err := dao.GetBlock(hash)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, gotBlock)
|
|
}
|
|
|
|
func TestGetVersion_NoVersion(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
version, err := dao.GetVersion()
|
|
require.Error(t, err)
|
|
require.Equal(t, "", version)
|
|
}
|
|
|
|
func TestGetVersion(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
err := dao.PutVersion("testVersion")
|
|
require.NoError(t, err)
|
|
version, err := dao.GetVersion()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, version)
|
|
}
|
|
|
|
func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
height, err := dao.GetCurrentBlockHeight()
|
|
require.Error(t, err)
|
|
require.Equal(t, uint32(0), height)
|
|
}
|
|
|
|
func TestGetCurrentHeaderHeight_Store(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
b := &block.Block{
|
|
Base: block.Base{
|
|
Script: transaction.Witness{
|
|
VerificationScript: []byte{byte(opcode.PUSH1)},
|
|
InvocationScript: []byte{byte(opcode.NOP)},
|
|
},
|
|
},
|
|
}
|
|
err := dao.StoreAsCurrentBlock(b)
|
|
require.NoError(t, err)
|
|
height, err := dao.GetCurrentBlockHeight()
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint32(0), height)
|
|
}
|
|
|
|
func TestStoreAsTransaction(t *testing.T) {
|
|
dao := newDao(storage.NewMemoryStore())
|
|
tx := &transaction.Transaction{Type: transaction.IssueType, Data: &transaction.IssueTX{}}
|
|
hash := tx.Hash()
|
|
err := dao.StoreAsTransaction(tx, 0)
|
|
require.NoError(t, err)
|
|
hasTransaction := dao.HasTransaction(hash)
|
|
require.True(t, hasTransaction)
|
|
}
|