core: wrap cached dao properly, don't miss cached data
Fixes #817 where invoked contract missed updated account information because it got it one layer below cachedDao used to process the block.
This commit is contained in:
parent
f64aa201c7
commit
5f09381cf4
12 changed files with 251 additions and 113 deletions
|
@ -80,7 +80,7 @@ type Blockchain struct {
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
|
|
||||||
// Data access object for CRUD operations around storage.
|
// Data access object for CRUD operations around storage.
|
||||||
dao *dao
|
dao *simpleDao
|
||||||
|
|
||||||
// Current index/height of the highest block.
|
// Current index/height of the highest block.
|
||||||
// Read access should always be called by BlockHeight().
|
// Read access should always be called by BlockHeight().
|
||||||
|
@ -154,7 +154,7 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L
|
||||||
}
|
}
|
||||||
bc := &Blockchain{
|
bc := &Blockchain{
|
||||||
config: cfg,
|
config: cfg,
|
||||||
dao: newDao(s),
|
dao: newSimpleDao(s),
|
||||||
headersOp: make(chan headersOpFunc),
|
headersOp: make(chan headersOpFunc),
|
||||||
headersOpDone: make(chan struct{}),
|
headersOpDone: make(chan struct{}),
|
||||||
stopCh: make(chan struct{}),
|
stopCh: make(chan struct{}),
|
||||||
|
@ -457,7 +457,7 @@ func (bc *Blockchain) getSystemFeeAmount(h util.Uint256) uint32 {
|
||||||
// is happening here, quite allot as you can see :). If things are wired together
|
// is happening here, quite allot as you can see :). If things are wired together
|
||||||
// and all tests are in place, we can make a more optimized and cleaner implementation.
|
// and all tests are in place, we can make a more optimized and cleaner implementation.
|
||||||
func (bc *Blockchain) storeBlock(block *block.Block) error {
|
func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
cache := newCachedDao(bc.dao.store)
|
cache := newCachedDao(bc.dao)
|
||||||
fee := bc.getSystemFeeAmount(block.PrevHash)
|
fee := bc.getSystemFeeAmount(block.PrevHash)
|
||||||
for _, tx := range block.Transactions {
|
for _, tx := range block.Transactions {
|
||||||
fee += uint32(bc.SystemFee(tx).IntegralValue())
|
fee += uint32(bc.SystemFee(tx).IntegralValue())
|
||||||
|
@ -655,7 +655,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case *transaction.InvocationTX:
|
case *transaction.InvocationTX:
|
||||||
systemInterop := bc.newInteropContext(trigger.Application, cache.store, block, tx)
|
systemInterop := bc.newInteropContext(trigger.Application, cache, block, tx)
|
||||||
v := bc.spawnVMWithInterops(systemInterop)
|
v := bc.spawnVMWithInterops(systemInterop)
|
||||||
v.SetCheckedHash(tx.VerificationHash().BytesBE())
|
v.SetCheckedHash(tx.VerificationHash().BytesBE())
|
||||||
v.LoadScript(t.Script)
|
v.LoadScript(t.Script)
|
||||||
|
@ -721,7 +721,7 @@ func (bc *Blockchain) storeBlock(block *block.Block) error {
|
||||||
defer bc.lock.Unlock()
|
defer bc.lock.Unlock()
|
||||||
|
|
||||||
if bc.config.SaveStorageBatch {
|
if bc.config.SaveStorageBatch {
|
||||||
bc.lastBatch = cache.dao.store.GetBatch()
|
bc.lastBatch = cache.dao.GetBatch()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := cache.Persist()
|
_, err := cache.Persist()
|
||||||
|
@ -1725,7 +1725,7 @@ func (bc *Blockchain) GetStandByValidators() (keys.PublicKeys, error) {
|
||||||
// GetValidators returns validators.
|
// GetValidators returns validators.
|
||||||
// Golang implementation of GetValidators method in C# (https://github.com/neo-project/neo/blob/c64748ecbac3baeb8045b16af0d518398a6ced24/neo/Persistence/Snapshot.cs#L182)
|
// Golang implementation of GetValidators method in C# (https://github.com/neo-project/neo/blob/c64748ecbac3baeb8045b16af0d518398a6ced24/neo/Persistence/Snapshot.cs#L182)
|
||||||
func (bc *Blockchain) GetValidators(txes ...*transaction.Transaction) ([]*keys.PublicKey, error) {
|
func (bc *Blockchain) GetValidators(txes ...*transaction.Transaction) ([]*keys.PublicKey, error) {
|
||||||
cache := newCachedDao(bc.dao.store)
|
cache := newCachedDao(bc.dao)
|
||||||
if len(txes) > 0 {
|
if len(txes) > 0 {
|
||||||
for _, tx := range txes {
|
for _, tx := range txes {
|
||||||
// iterate through outputs
|
// iterate through outputs
|
||||||
|
@ -2016,12 +2016,11 @@ func (bc *Blockchain) spawnVMWithInterops(interopCtx *interopContext) *vm.VM {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTestVM returns a VM and a Store setup for a test run of some sort of code.
|
// GetTestVM returns a VM and a Store setup for a test run of some sort of code.
|
||||||
func (bc *Blockchain) GetTestVM() (*vm.VM, storage.Store) {
|
func (bc *Blockchain) GetTestVM() *vm.VM {
|
||||||
tmpStore := storage.NewMemCachedStore(bc.dao.store)
|
systemInterop := bc.newInteropContext(trigger.Application, bc.dao, nil, nil)
|
||||||
systemInterop := bc.newInteropContext(trigger.Application, tmpStore, nil, nil)
|
|
||||||
vm := bc.spawnVMWithInterops(systemInterop)
|
vm := bc.spawnVMWithInterops(systemInterop)
|
||||||
vm.SetPriceGetter(getPrice)
|
vm.SetPriceGetter(getPrice)
|
||||||
return vm, tmpStore
|
return vm
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScriptFromWitness returns verification script for provided witness.
|
// ScriptFromWitness returns verification script for provided witness.
|
||||||
|
@ -2106,7 +2105,7 @@ func (bc *Blockchain) verifyTxWitnesses(t *transaction.Transaction, block *block
|
||||||
}
|
}
|
||||||
sort.Slice(hashes, func(i, j int) bool { return hashes[i].Less(hashes[j]) })
|
sort.Slice(hashes, func(i, j int) bool { return hashes[i].Less(hashes[j]) })
|
||||||
sort.Slice(witnesses, func(i, j int) bool { return witnesses[i].ScriptHash().Less(witnesses[j].ScriptHash()) })
|
sort.Slice(witnesses, func(i, j int) bool { return witnesses[i].ScriptHash().Less(witnesses[j].ScriptHash()) })
|
||||||
interopCtx := bc.newInteropContext(trigger.Verification, bc.dao.store, block, t)
|
interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, block, t)
|
||||||
for i := 0; i < len(hashes); i++ {
|
for i := 0; i < len(hashes); i++ {
|
||||||
err := bc.verifyHashAgainstScript(hashes[i], &witnesses[i], t.VerificationHash(), interopCtx, false)
|
err := bc.verifyHashAgainstScript(hashes[i], &witnesses[i], t.VerificationHash(), interopCtx, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2126,7 +2125,7 @@ func (bc *Blockchain) verifyHeaderWitnesses(currHeader, prevHeader *block.Header
|
||||||
} else {
|
} else {
|
||||||
hash = prevHeader.NextConsensus
|
hash = prevHeader.NextConsensus
|
||||||
}
|
}
|
||||||
interopCtx := bc.newInteropContext(trigger.Verification, bc.dao.store, nil, nil)
|
interopCtx := bc.newInteropContext(trigger.Verification, bc.dao, nil, nil)
|
||||||
return bc.verifyHashAgainstScript(hash, &currHeader.Script, currHeader.VerificationHash(), interopCtx, true)
|
return bc.verifyHashAgainstScript(hash, &currHeader.Script, currHeader.VerificationHash(), interopCtx, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2141,6 +2140,6 @@ func (bc *Blockchain) secondsPerBlock() int {
|
||||||
return bc.config.SecondsPerBlock
|
return bc.config.SecondsPerBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *Blockchain) newInteropContext(trigger trigger.Type, s storage.Store, block *block.Block, tx *transaction.Transaction) *interopContext {
|
func (bc *Blockchain) newInteropContext(trigger trigger.Type, d dao, block *block.Block, tx *transaction.Transaction) *interopContext {
|
||||||
return newInteropContext(trigger, bc, s, block, tx, bc.log)
|
return newInteropContext(trigger, bc, d, block, tx, bc.log)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -41,7 +40,7 @@ type Blockchainer interface {
|
||||||
GetScriptHashesForVerifying(*transaction.Transaction) ([]util.Uint160, error)
|
GetScriptHashesForVerifying(*transaction.Transaction) ([]util.Uint160, error)
|
||||||
GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem
|
GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem
|
||||||
GetStorageItems(hash util.Uint160) (map[string]*state.StorageItem, error)
|
GetStorageItems(hash util.Uint160) (map[string]*state.StorageItem, error)
|
||||||
GetTestVM() (*vm.VM, storage.Store)
|
GetTestVM() *vm.VM
|
||||||
GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error)
|
GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error)
|
||||||
GetUnspentCoinState(util.Uint256) *state.UnspentCoin
|
GetUnspentCoinState(util.Uint256) *state.UnspentCoin
|
||||||
References(t *transaction.Transaction) ([]transaction.InOut, error)
|
References(t *transaction.Transaction) ([]transaction.InOut, error)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
)
|
)
|
||||||
|
@ -20,13 +21,13 @@ type cachedDao struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// newCachedDao returns new cachedDao wrapping around given backing store.
|
// newCachedDao returns new cachedDao wrapping around given backing store.
|
||||||
func newCachedDao(backend storage.Store) *cachedDao {
|
func newCachedDao(d dao) *cachedDao {
|
||||||
accs := make(map[util.Uint160]*state.Account)
|
accs := make(map[util.Uint160]*state.Account)
|
||||||
ctrs := make(map[util.Uint160]*state.Contract)
|
ctrs := make(map[util.Uint160]*state.Contract)
|
||||||
unspents := make(map[util.Uint256]*state.UnspentCoin)
|
unspents := make(map[util.Uint256]*state.UnspentCoin)
|
||||||
balances := make(map[util.Uint160]*state.NEP5Balances)
|
balances := make(map[util.Uint160]*state.NEP5Balances)
|
||||||
transfers := make(map[util.Uint160]map[uint32]*state.NEP5TransferLog)
|
transfers := make(map[util.Uint160]map[uint32]*state.NEP5TransferLog)
|
||||||
return &cachedDao{*newDao(backend), accs, ctrs, unspents, balances, transfers}
|
return &cachedDao{d.GetWrapped(), accs, ctrs, unspents, balances, transfers}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountStateOrNew retrieves Account from cache or underlying Store
|
// GetAccountStateOrNew retrieves Account from cache or underlying Store
|
||||||
|
@ -139,6 +140,24 @@ func (cd *cachedDao) AppendNEP5Transfer(acc util.Uint160, index uint32, tr *stat
|
||||||
// Persist flushes all the changes made into the (supposedly) persistent
|
// Persist flushes all the changes made into the (supposedly) persistent
|
||||||
// underlying store.
|
// underlying store.
|
||||||
func (cd *cachedDao) Persist() (int, error) {
|
func (cd *cachedDao) Persist() (int, error) {
|
||||||
|
lowerCache, ok := cd.dao.(*cachedDao)
|
||||||
|
// If the lower dao is cachedDao, we only need to flush the MemCached DB.
|
||||||
|
// This actually breaks dao interface incapsulation, but for our current
|
||||||
|
// usage scenario it should be good enough if cd doesn't modify object
|
||||||
|
// caches (accounts/contracts/etc) in any way.
|
||||||
|
if ok {
|
||||||
|
var simpleCache *simpleDao
|
||||||
|
for simpleCache == nil {
|
||||||
|
simpleCache, ok = lowerCache.dao.(*simpleDao)
|
||||||
|
if !ok {
|
||||||
|
lowerCache, ok = cd.dao.(*cachedDao)
|
||||||
|
if !ok {
|
||||||
|
return 0, errors.New("unsupported lower dao")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return simpleCache.Persist()
|
||||||
|
}
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
|
|
||||||
for sc := range cd.accounts {
|
for sc := range cd.accounts {
|
||||||
|
@ -172,3 +191,13 @@ func (cd *cachedDao) Persist() (int, error) {
|
||||||
}
|
}
|
||||||
return cd.dao.Persist()
|
return cd.dao.Persist()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cd *cachedDao) GetWrapped() dao {
|
||||||
|
return &cachedDao{cd.dao.GetWrapped(),
|
||||||
|
cd.accounts,
|
||||||
|
cd.contracts,
|
||||||
|
cd.unspents,
|
||||||
|
cd.balances,
|
||||||
|
cd.transfers,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,15 +8,16 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/internal/random"
|
"github.com/nspcc-dev/neo-go/pkg/internal/random"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCachedDaoAccounts(t *testing.T) {
|
func TestCachedDaoAccounts(t *testing.T) {
|
||||||
store := storage.NewMemoryStore()
|
store := storage.NewMemoryStore()
|
||||||
// Persistent DAO to check for backing storage.
|
// Persistent DAO to check for backing storage.
|
||||||
pdao := newDao(store)
|
pdao := newSimpleDao(store)
|
||||||
// Cached DAO.
|
// Cached DAO.
|
||||||
cdao := newCachedDao(store)
|
cdao := newCachedDao(pdao)
|
||||||
|
|
||||||
hash := random.Uint160()
|
hash := random.Uint160()
|
||||||
_, err := cdao.GetAccountState(hash)
|
_, err := cdao.GetAccountState(hash)
|
||||||
|
@ -50,7 +51,8 @@ func TestCachedDaoAccounts(t *testing.T) {
|
||||||
|
|
||||||
func TestCachedDaoContracts(t *testing.T) {
|
func TestCachedDaoContracts(t *testing.T) {
|
||||||
store := storage.NewMemoryStore()
|
store := storage.NewMemoryStore()
|
||||||
dao := newCachedDao(store)
|
pdao := newSimpleDao(store)
|
||||||
|
dao := newCachedDao(pdao)
|
||||||
|
|
||||||
script := []byte{0xde, 0xad, 0xbe, 0xef}
|
script := []byte{0xde, 0xad, 0xbe, 0xef}
|
||||||
sh := hash.Hash160(script)
|
sh := hash.Hash160(script)
|
||||||
|
@ -69,7 +71,7 @@ func TestCachedDaoContracts(t *testing.T) {
|
||||||
|
|
||||||
_, err = dao.Persist()
|
_, err = dao.Persist()
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
dao2 := newCachedDao(store)
|
dao2 := newCachedDao(pdao)
|
||||||
cs2, err = dao2.GetContractState(sh)
|
cs2, err = dao2.GetContractState(sh)
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Equal(t, cs, cs2)
|
require.Equal(t, cs, cs2)
|
||||||
|
@ -81,3 +83,49 @@ func TestCachedDaoContracts(t *testing.T) {
|
||||||
_, err = dao.GetContractState(sh)
|
_, err = dao.GetContractState(sh)
|
||||||
require.NotNil(t, err)
|
require.NotNil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCachedCachedDao(t *testing.T) {
|
||||||
|
store := storage.NewMemoryStore()
|
||||||
|
// Persistent DAO to check for backing storage.
|
||||||
|
pdao := newSimpleDao(store)
|
||||||
|
assert.NotEqual(t, store, pdao.store)
|
||||||
|
// Cached DAO.
|
||||||
|
cdao := newCachedDao(pdao)
|
||||||
|
cdaoDao := cdao.dao.(*simpleDao)
|
||||||
|
assert.NotEqual(t, store, cdaoDao.store)
|
||||||
|
assert.NotEqual(t, pdao.store, cdaoDao.store)
|
||||||
|
|
||||||
|
// Cached cached DAO.
|
||||||
|
ccdao := newCachedDao(cdao)
|
||||||
|
ccdaoDao := ccdao.dao.(*cachedDao)
|
||||||
|
intDao := ccdaoDao.dao.(*simpleDao)
|
||||||
|
assert.NotEqual(t, store, intDao.store)
|
||||||
|
assert.NotEqual(t, pdao.store, intDao.store)
|
||||||
|
assert.NotEqual(t, cdaoDao.store, intDao.store)
|
||||||
|
|
||||||
|
hash := random.Uint160()
|
||||||
|
key := []byte("qwerty")
|
||||||
|
si := &state.StorageItem{Value: []byte("poiuyt")}
|
||||||
|
require.NoError(t, ccdao.PutStorageItem(hash, key, si))
|
||||||
|
resi := ccdao.GetStorageItem(hash, key)
|
||||||
|
assert.Equal(t, si, resi)
|
||||||
|
|
||||||
|
resi = cdao.GetStorageItem(hash, key)
|
||||||
|
assert.Equal(t, (*state.StorageItem)(nil), resi)
|
||||||
|
resi = pdao.GetStorageItem(hash, key)
|
||||||
|
assert.Equal(t, (*state.StorageItem)(nil), resi)
|
||||||
|
|
||||||
|
cnt, err := ccdao.Persist()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, cnt)
|
||||||
|
resi = cdao.GetStorageItem(hash, key)
|
||||||
|
assert.Equal(t, si, resi)
|
||||||
|
resi = pdao.GetStorageItem(hash, key)
|
||||||
|
assert.Equal(t, (*state.StorageItem)(nil), resi)
|
||||||
|
|
||||||
|
cnt, err = cdao.Persist()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 1, cnt)
|
||||||
|
resi = pdao.GetStorageItem(hash, key)
|
||||||
|
assert.Equal(t, si, resi)
|
||||||
|
}
|
||||||
|
|
170
pkg/core/dao.go
170
pkg/core/dao.go
|
@ -16,16 +16,80 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// dao is a data access object.
|
// dao is a data access object.
|
||||||
type dao struct {
|
type dao interface {
|
||||||
|
AppendNEP5Transfer(acc util.Uint160, index uint32, tr *state.NEP5Transfer) (bool, error)
|
||||||
|
DeleteContractState(hash util.Uint160) error
|
||||||
|
DeleteStorageItem(scripthash util.Uint160, key []byte) error
|
||||||
|
DeleteValidatorState(vs *state.Validator) error
|
||||||
|
GetAccountState(hash util.Uint160) (*state.Account, error)
|
||||||
|
GetAccountStateOrNew(hash util.Uint160) (*state.Account, error)
|
||||||
|
GetAndDecode(entity io.Serializable, key []byte) error
|
||||||
|
GetAppExecResult(hash util.Uint256) (*state.AppExecResult, error)
|
||||||
|
GetAssetState(assetID util.Uint256) (*state.Asset, error)
|
||||||
|
GetBatch() *storage.MemBatch
|
||||||
|
GetBlock(hash util.Uint256) (*block.Block, uint32, error)
|
||||||
|
GetContractState(hash util.Uint160) (*state.Contract, error)
|
||||||
|
GetCurrentBlockHeight() (uint32, error)
|
||||||
|
GetCurrentHeaderHeight() (i uint32, h util.Uint256, err error)
|
||||||
|
GetHeaderHashes() ([]util.Uint256, error)
|
||||||
|
GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error)
|
||||||
|
GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5TransferLog, error)
|
||||||
|
GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem
|
||||||
|
GetStorageItems(hash util.Uint160) (map[string]*state.StorageItem, error)
|
||||||
|
GetTransaction(hash util.Uint256) (*transaction.Transaction, uint32, error)
|
||||||
|
GetUnspentCoinState(hash util.Uint256) (*state.UnspentCoin, error)
|
||||||
|
GetValidatorState(publicKey *keys.PublicKey) (*state.Validator, error)
|
||||||
|
GetValidatorStateOrNew(publicKey *keys.PublicKey) (*state.Validator, error)
|
||||||
|
GetValidators() []*state.Validator
|
||||||
|
GetValidatorsCount() (*state.ValidatorsCount, error)
|
||||||
|
GetVersion() (string, error)
|
||||||
|
GetWrapped() dao
|
||||||
|
HasTransaction(hash util.Uint256) bool
|
||||||
|
IsDoubleClaim(claim *transaction.ClaimTX) bool
|
||||||
|
IsDoubleSpend(tx *transaction.Transaction) bool
|
||||||
|
Persist() (int, error)
|
||||||
|
PutAccountState(as *state.Account) error
|
||||||
|
PutAppExecResult(aer *state.AppExecResult) error
|
||||||
|
PutAssetState(as *state.Asset) error
|
||||||
|
PutContractState(cs *state.Contract) error
|
||||||
|
PutCurrentHeader(hashAndIndex []byte) error
|
||||||
|
PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) error
|
||||||
|
PutNEP5TransferLog(acc util.Uint160, index uint32, lg *state.NEP5TransferLog) error
|
||||||
|
PutStorageItem(scripthash util.Uint160, key []byte, si *state.StorageItem) error
|
||||||
|
PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error
|
||||||
|
PutValidatorState(vs *state.Validator) error
|
||||||
|
PutValidatorsCount(vc *state.ValidatorsCount) error
|
||||||
|
PutVersion(v string) error
|
||||||
|
StoreAsBlock(block *block.Block, sysFee uint32) error
|
||||||
|
StoreAsCurrentBlock(block *block.Block) error
|
||||||
|
StoreAsTransaction(tx *transaction.Transaction, index uint32) error
|
||||||
|
putAccountState(as *state.Account, buf *io.BufBinWriter) error
|
||||||
|
putNEP5Balances(acc util.Uint160, bs *state.NEP5Balances, buf *io.BufBinWriter) error
|
||||||
|
putUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin, buf *io.BufBinWriter) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// simpleDao is memCached wrapper around DB, simple dao implementation.
|
||||||
|
type simpleDao struct {
|
||||||
store *storage.MemCachedStore
|
store *storage.MemCachedStore
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDao(backend storage.Store) *dao {
|
func newSimpleDao(backend storage.Store) *simpleDao {
|
||||||
return &dao{store: storage.NewMemCachedStore(backend)}
|
return &simpleDao{store: storage.NewMemCachedStore(backend)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBatch returns currently accumulated DB changeset.
|
||||||
|
func (dao *simpleDao) GetBatch() *storage.MemBatch {
|
||||||
|
return dao.store.GetBatch()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWrapped returns new dao instance with another layer of wrapped
|
||||||
|
// MemCachedStore around the current dao store.
|
||||||
|
func (dao *simpleDao) GetWrapped() dao {
|
||||||
|
return newSimpleDao(dao.store)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAndDecode performs get operation and decoding with serializable structures.
|
// GetAndDecode performs get operation and decoding with serializable structures.
|
||||||
func (dao *dao) GetAndDecode(entity io.Serializable, key []byte) error {
|
func (dao *simpleDao) GetAndDecode(entity io.Serializable, key []byte) error {
|
||||||
entityBytes, err := dao.store.Get(key)
|
entityBytes, err := dao.store.Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -36,12 +100,12 @@ func (dao *dao) GetAndDecode(entity io.Serializable, key []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put performs put operation with serializable structures.
|
// Put performs put operation with serializable structures.
|
||||||
func (dao *dao) Put(entity io.Serializable, key []byte) error {
|
func (dao *simpleDao) Put(entity io.Serializable, key []byte) error {
|
||||||
return dao.putWithBuffer(entity, key, io.NewBufBinWriter())
|
return dao.putWithBuffer(entity, key, io.NewBufBinWriter())
|
||||||
}
|
}
|
||||||
|
|
||||||
// putWithBuffer performs put operation using buf as a pre-allocated buffer for serialization.
|
// putWithBuffer performs put operation using buf as a pre-allocated buffer for serialization.
|
||||||
func (dao *dao) putWithBuffer(entity io.Serializable, key []byte, buf *io.BufBinWriter) error {
|
func (dao *simpleDao) putWithBuffer(entity io.Serializable, key []byte, buf *io.BufBinWriter) error {
|
||||||
entity.EncodeBinary(buf.BinWriter)
|
entity.EncodeBinary(buf.BinWriter)
|
||||||
if buf.Err != nil {
|
if buf.Err != nil {
|
||||||
return buf.Err
|
return buf.Err
|
||||||
|
@ -53,7 +117,7 @@ func (dao *dao) putWithBuffer(entity io.Serializable, key []byte, buf *io.BufBin
|
||||||
|
|
||||||
// GetAccountStateOrNew retrieves Account from temporary or persistent Store
|
// GetAccountStateOrNew retrieves Account from temporary or persistent Store
|
||||||
// or creates a new one if it doesn't exist and persists it.
|
// or creates a new one if it doesn't exist and persists it.
|
||||||
func (dao *dao) GetAccountStateOrNew(hash util.Uint160) (*state.Account, error) {
|
func (dao *simpleDao) GetAccountStateOrNew(hash util.Uint160) (*state.Account, error) {
|
||||||
account, err := dao.GetAccountState(hash)
|
account, err := dao.GetAccountState(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != storage.ErrKeyNotFound {
|
if err != storage.ErrKeyNotFound {
|
||||||
|
@ -66,7 +130,7 @@ func (dao *dao) GetAccountStateOrNew(hash util.Uint160) (*state.Account, error)
|
||||||
|
|
||||||
// GetAccountState returns Account from the given Store if it's
|
// GetAccountState returns Account from the given Store if it's
|
||||||
// present there. Returns nil otherwise.
|
// present there. Returns nil otherwise.
|
||||||
func (dao *dao) GetAccountState(hash util.Uint160) (*state.Account, error) {
|
func (dao *simpleDao) GetAccountState(hash util.Uint160) (*state.Account, error) {
|
||||||
account := &state.Account{}
|
account := &state.Account{}
|
||||||
key := storage.AppendPrefix(storage.STAccount, hash.BytesBE())
|
key := storage.AppendPrefix(storage.STAccount, hash.BytesBE())
|
||||||
err := dao.GetAndDecode(account, key)
|
err := dao.GetAndDecode(account, key)
|
||||||
|
@ -76,11 +140,11 @@ func (dao *dao) GetAccountState(hash util.Uint160) (*state.Account, error) {
|
||||||
return account, err
|
return account, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dao *dao) PutAccountState(as *state.Account) error {
|
func (dao *simpleDao) PutAccountState(as *state.Account) error {
|
||||||
return dao.putAccountState(as, io.NewBufBinWriter())
|
return dao.putAccountState(as, io.NewBufBinWriter())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dao *dao) putAccountState(as *state.Account, buf *io.BufBinWriter) error {
|
func (dao *simpleDao) putAccountState(as *state.Account, buf *io.BufBinWriter) error {
|
||||||
key := storage.AppendPrefix(storage.STAccount, as.ScriptHash.BytesBE())
|
key := storage.AppendPrefix(storage.STAccount, as.ScriptHash.BytesBE())
|
||||||
return dao.putWithBuffer(as, key, buf)
|
return dao.putWithBuffer(as, key, buf)
|
||||||
}
|
}
|
||||||
|
@ -90,7 +154,7 @@ func (dao *dao) putAccountState(as *state.Account, buf *io.BufBinWriter) error {
|
||||||
// -- start assets.
|
// -- start assets.
|
||||||
|
|
||||||
// GetAssetState returns given asset state as recorded in the given store.
|
// GetAssetState returns given asset state as recorded in the given store.
|
||||||
func (dao *dao) GetAssetState(assetID util.Uint256) (*state.Asset, error) {
|
func (dao *simpleDao) GetAssetState(assetID util.Uint256) (*state.Asset, error) {
|
||||||
asset := &state.Asset{}
|
asset := &state.Asset{}
|
||||||
key := storage.AppendPrefix(storage.STAsset, assetID.BytesBE())
|
key := storage.AppendPrefix(storage.STAsset, assetID.BytesBE())
|
||||||
err := dao.GetAndDecode(asset, key)
|
err := dao.GetAndDecode(asset, key)
|
||||||
|
@ -104,7 +168,7 @@ func (dao *dao) GetAssetState(assetID util.Uint256) (*state.Asset, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutAssetState puts given asset state into the given store.
|
// PutAssetState puts given asset state into the given store.
|
||||||
func (dao *dao) PutAssetState(as *state.Asset) error {
|
func (dao *simpleDao) PutAssetState(as *state.Asset) error {
|
||||||
key := storage.AppendPrefix(storage.STAsset, as.ID.BytesBE())
|
key := storage.AppendPrefix(storage.STAsset, as.ID.BytesBE())
|
||||||
return dao.Put(as, key)
|
return dao.Put(as, key)
|
||||||
}
|
}
|
||||||
|
@ -115,7 +179,7 @@ func (dao *dao) PutAssetState(as *state.Asset) error {
|
||||||
|
|
||||||
// GetContractState returns contract state as recorded in the given
|
// GetContractState returns contract state as recorded in the given
|
||||||
// store by the given script hash.
|
// store by the given script hash.
|
||||||
func (dao *dao) GetContractState(hash util.Uint160) (*state.Contract, error) {
|
func (dao *simpleDao) GetContractState(hash util.Uint160) (*state.Contract, error) {
|
||||||
contract := &state.Contract{}
|
contract := &state.Contract{}
|
||||||
key := storage.AppendPrefix(storage.STContract, hash.BytesBE())
|
key := storage.AppendPrefix(storage.STContract, hash.BytesBE())
|
||||||
err := dao.GetAndDecode(contract, key)
|
err := dao.GetAndDecode(contract, key)
|
||||||
|
@ -130,13 +194,13 @@ func (dao *dao) GetContractState(hash util.Uint160) (*state.Contract, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutContractState puts given contract state into the given store.
|
// PutContractState puts given contract state into the given store.
|
||||||
func (dao *dao) PutContractState(cs *state.Contract) error {
|
func (dao *simpleDao) PutContractState(cs *state.Contract) error {
|
||||||
key := storage.AppendPrefix(storage.STContract, cs.ScriptHash().BytesBE())
|
key := storage.AppendPrefix(storage.STContract, cs.ScriptHash().BytesBE())
|
||||||
return dao.Put(cs, key)
|
return dao.Put(cs, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteContractState deletes given contract state in the given store.
|
// DeleteContractState deletes given contract state in the given store.
|
||||||
func (dao *dao) DeleteContractState(hash util.Uint160) error {
|
func (dao *simpleDao) DeleteContractState(hash util.Uint160) error {
|
||||||
key := storage.AppendPrefix(storage.STContract, hash.BytesBE())
|
key := storage.AppendPrefix(storage.STContract, hash.BytesBE())
|
||||||
return dao.store.Delete(key)
|
return dao.store.Delete(key)
|
||||||
}
|
}
|
||||||
|
@ -146,7 +210,7 @@ func (dao *dao) DeleteContractState(hash util.Uint160) error {
|
||||||
// -- start nep5 balances.
|
// -- start nep5 balances.
|
||||||
|
|
||||||
// GetNEP5Balances retrieves nep5 balances from the cache.
|
// GetNEP5Balances retrieves nep5 balances from the cache.
|
||||||
func (dao *dao) GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error) {
|
func (dao *simpleDao) GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error) {
|
||||||
key := storage.AppendPrefix(storage.STNEP5Balances, acc.BytesBE())
|
key := storage.AppendPrefix(storage.STNEP5Balances, acc.BytesBE())
|
||||||
bs := state.NewNEP5Balances()
|
bs := state.NewNEP5Balances()
|
||||||
err := dao.GetAndDecode(bs, key)
|
err := dao.GetAndDecode(bs, key)
|
||||||
|
@ -157,11 +221,11 @@ func (dao *dao) GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutNEP5Balances saves nep5 balances from the cache.
|
// PutNEP5Balances saves nep5 balances from the cache.
|
||||||
func (dao *dao) PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) error {
|
func (dao *simpleDao) PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) error {
|
||||||
return dao.putNEP5Balances(acc, bs, io.NewBufBinWriter())
|
return dao.putNEP5Balances(acc, bs, io.NewBufBinWriter())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dao *dao) putNEP5Balances(acc util.Uint160, bs *state.NEP5Balances, buf *io.BufBinWriter) error {
|
func (dao *simpleDao) putNEP5Balances(acc util.Uint160, bs *state.NEP5Balances, buf *io.BufBinWriter) error {
|
||||||
key := storage.AppendPrefix(storage.STNEP5Balances, acc.BytesBE())
|
key := storage.AppendPrefix(storage.STNEP5Balances, acc.BytesBE())
|
||||||
return dao.putWithBuffer(bs, key, buf)
|
return dao.putWithBuffer(bs, key, buf)
|
||||||
}
|
}
|
||||||
|
@ -181,7 +245,7 @@ func getNEP5TransferLogKey(acc util.Uint160, index uint32) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNEP5TransferLog retrieves transfer log from the cache.
|
// GetNEP5TransferLog retrieves transfer log from the cache.
|
||||||
func (dao *dao) GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5TransferLog, error) {
|
func (dao *simpleDao) GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5TransferLog, error) {
|
||||||
key := getNEP5TransferLogKey(acc, index)
|
key := getNEP5TransferLogKey(acc, index)
|
||||||
value, err := dao.store.Get(key)
|
value, err := dao.store.Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -194,14 +258,14 @@ func (dao *dao) GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5T
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutNEP5TransferLog saves given transfer log in the cache.
|
// PutNEP5TransferLog saves given transfer log in the cache.
|
||||||
func (dao *dao) PutNEP5TransferLog(acc util.Uint160, index uint32, lg *state.NEP5TransferLog) error {
|
func (dao *simpleDao) PutNEP5TransferLog(acc util.Uint160, index uint32, lg *state.NEP5TransferLog) error {
|
||||||
key := getNEP5TransferLogKey(acc, index)
|
key := getNEP5TransferLogKey(acc, index)
|
||||||
return dao.store.Put(key, lg.Raw)
|
return dao.store.Put(key, lg.Raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppendNEP5Transfer appends a single NEP5 transfer to a log.
|
// AppendNEP5Transfer appends a single NEP5 transfer to a log.
|
||||||
// First return value signalizes that log size has exceeded batch size.
|
// First return value signalizes that log size has exceeded batch size.
|
||||||
func (dao *dao) AppendNEP5Transfer(acc util.Uint160, index uint32, tr *state.NEP5Transfer) (bool, error) {
|
func (dao *simpleDao) AppendNEP5Transfer(acc util.Uint160, index uint32, tr *state.NEP5Transfer) (bool, error) {
|
||||||
lg, err := dao.GetNEP5TransferLog(acc, index)
|
lg, err := dao.GetNEP5TransferLog(acc, index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != storage.ErrKeyNotFound {
|
if err != storage.ErrKeyNotFound {
|
||||||
|
@ -220,7 +284,7 @@ func (dao *dao) AppendNEP5Transfer(acc util.Uint160, index uint32, tr *state.NEP
|
||||||
// -- start unspent coins.
|
// -- start unspent coins.
|
||||||
|
|
||||||
// GetUnspentCoinState retrieves UnspentCoinState from the given store.
|
// GetUnspentCoinState retrieves UnspentCoinState from the given store.
|
||||||
func (dao *dao) GetUnspentCoinState(hash util.Uint256) (*state.UnspentCoin, error) {
|
func (dao *simpleDao) GetUnspentCoinState(hash util.Uint256) (*state.UnspentCoin, error) {
|
||||||
unspent := &state.UnspentCoin{}
|
unspent := &state.UnspentCoin{}
|
||||||
key := storage.AppendPrefix(storage.STCoin, hash.BytesLE())
|
key := storage.AppendPrefix(storage.STCoin, hash.BytesLE())
|
||||||
err := dao.GetAndDecode(unspent, key)
|
err := dao.GetAndDecode(unspent, key)
|
||||||
|
@ -231,11 +295,11 @@ func (dao *dao) GetUnspentCoinState(hash util.Uint256) (*state.UnspentCoin, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutUnspentCoinState puts given UnspentCoinState into the given store.
|
// PutUnspentCoinState puts given UnspentCoinState into the given store.
|
||||||
func (dao *dao) PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error {
|
func (dao *simpleDao) PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error {
|
||||||
return dao.putUnspentCoinState(hash, ucs, io.NewBufBinWriter())
|
return dao.putUnspentCoinState(hash, ucs, io.NewBufBinWriter())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dao *dao) putUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin, buf *io.BufBinWriter) error {
|
func (dao *simpleDao) putUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin, buf *io.BufBinWriter) error {
|
||||||
key := storage.AppendPrefix(storage.STCoin, hash.BytesLE())
|
key := storage.AppendPrefix(storage.STCoin, hash.BytesLE())
|
||||||
return dao.putWithBuffer(ucs, key, buf)
|
return dao.putWithBuffer(ucs, key, buf)
|
||||||
}
|
}
|
||||||
|
@ -245,7 +309,7 @@ func (dao *dao) putUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin, b
|
||||||
// -- start validator.
|
// -- start validator.
|
||||||
|
|
||||||
// GetValidatorStateOrNew gets validator from store or created new one in case of error.
|
// GetValidatorStateOrNew gets validator from store or created new one in case of error.
|
||||||
func (dao *dao) GetValidatorStateOrNew(publicKey *keys.PublicKey) (*state.Validator, error) {
|
func (dao *simpleDao) GetValidatorStateOrNew(publicKey *keys.PublicKey) (*state.Validator, error) {
|
||||||
validatorState, err := dao.GetValidatorState(publicKey)
|
validatorState, err := dao.GetValidatorState(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != storage.ErrKeyNotFound {
|
if err != storage.ErrKeyNotFound {
|
||||||
|
@ -258,7 +322,7 @@ func (dao *dao) GetValidatorStateOrNew(publicKey *keys.PublicKey) (*state.Valida
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetValidators returns all validators from store.
|
// GetValidators returns all validators from store.
|
||||||
func (dao *dao) GetValidators() []*state.Validator {
|
func (dao *simpleDao) GetValidators() []*state.Validator {
|
||||||
var validators []*state.Validator
|
var validators []*state.Validator
|
||||||
dao.store.Seek(storage.STValidator.Bytes(), func(k, v []byte) {
|
dao.store.Seek(storage.STValidator.Bytes(), func(k, v []byte) {
|
||||||
r := io.NewBinReaderFromBuf(v)
|
r := io.NewBinReaderFromBuf(v)
|
||||||
|
@ -273,7 +337,7 @@ func (dao *dao) GetValidators() []*state.Validator {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetValidatorState returns validator by publicKey.
|
// GetValidatorState returns validator by publicKey.
|
||||||
func (dao *dao) GetValidatorState(publicKey *keys.PublicKey) (*state.Validator, error) {
|
func (dao *simpleDao) GetValidatorState(publicKey *keys.PublicKey) (*state.Validator, error) {
|
||||||
validatorState := &state.Validator{}
|
validatorState := &state.Validator{}
|
||||||
key := storage.AppendPrefix(storage.STValidator, publicKey.Bytes())
|
key := storage.AppendPrefix(storage.STValidator, publicKey.Bytes())
|
||||||
err := dao.GetAndDecode(validatorState, key)
|
err := dao.GetAndDecode(validatorState, key)
|
||||||
|
@ -284,20 +348,20 @@ func (dao *dao) GetValidatorState(publicKey *keys.PublicKey) (*state.Validator,
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutValidatorState puts given Validator into the given store.
|
// PutValidatorState puts given Validator into the given store.
|
||||||
func (dao *dao) PutValidatorState(vs *state.Validator) error {
|
func (dao *simpleDao) PutValidatorState(vs *state.Validator) error {
|
||||||
key := storage.AppendPrefix(storage.STValidator, vs.PublicKey.Bytes())
|
key := storage.AppendPrefix(storage.STValidator, vs.PublicKey.Bytes())
|
||||||
return dao.Put(vs, key)
|
return dao.Put(vs, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteValidatorState deletes given Validator into the given store.
|
// DeleteValidatorState deletes given Validator into the given store.
|
||||||
func (dao *dao) DeleteValidatorState(vs *state.Validator) error {
|
func (dao *simpleDao) DeleteValidatorState(vs *state.Validator) error {
|
||||||
key := storage.AppendPrefix(storage.STValidator, vs.PublicKey.Bytes())
|
key := storage.AppendPrefix(storage.STValidator, vs.PublicKey.Bytes())
|
||||||
return dao.store.Delete(key)
|
return dao.store.Delete(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetValidatorsCount returns current ValidatorsCount or new one if there is none
|
// GetValidatorsCount returns current ValidatorsCount or new one if there is none
|
||||||
// in the DB.
|
// in the DB.
|
||||||
func (dao *dao) GetValidatorsCount() (*state.ValidatorsCount, error) {
|
func (dao *simpleDao) GetValidatorsCount() (*state.ValidatorsCount, error) {
|
||||||
vc := &state.ValidatorsCount{}
|
vc := &state.ValidatorsCount{}
|
||||||
key := []byte{byte(storage.IXValidatorsCount)}
|
key := []byte{byte(storage.IXValidatorsCount)}
|
||||||
err := dao.GetAndDecode(vc, key)
|
err := dao.GetAndDecode(vc, key)
|
||||||
|
@ -308,7 +372,7 @@ func (dao *dao) GetValidatorsCount() (*state.ValidatorsCount, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutValidatorsCount put given ValidatorsCount in the store.
|
// PutValidatorsCount put given ValidatorsCount in the store.
|
||||||
func (dao *dao) PutValidatorsCount(vc *state.ValidatorsCount) error {
|
func (dao *simpleDao) PutValidatorsCount(vc *state.ValidatorsCount) error {
|
||||||
key := []byte{byte(storage.IXValidatorsCount)}
|
key := []byte{byte(storage.IXValidatorsCount)}
|
||||||
return dao.Put(vc, key)
|
return dao.Put(vc, key)
|
||||||
}
|
}
|
||||||
|
@ -319,7 +383,7 @@ func (dao *dao) PutValidatorsCount(vc *state.ValidatorsCount) error {
|
||||||
|
|
||||||
// GetAppExecResult gets application execution result from the
|
// GetAppExecResult gets application execution result from the
|
||||||
// given store.
|
// given store.
|
||||||
func (dao *dao) GetAppExecResult(hash util.Uint256) (*state.AppExecResult, error) {
|
func (dao *simpleDao) GetAppExecResult(hash util.Uint256) (*state.AppExecResult, error) {
|
||||||
aer := &state.AppExecResult{}
|
aer := &state.AppExecResult{}
|
||||||
key := storage.AppendPrefix(storage.STNotification, hash.BytesBE())
|
key := storage.AppendPrefix(storage.STNotification, hash.BytesBE())
|
||||||
err := dao.GetAndDecode(aer, key)
|
err := dao.GetAndDecode(aer, key)
|
||||||
|
@ -331,7 +395,7 @@ func (dao *dao) GetAppExecResult(hash util.Uint256) (*state.AppExecResult, error
|
||||||
|
|
||||||
// PutAppExecResult puts given application execution result into the
|
// PutAppExecResult puts given application execution result into the
|
||||||
// given store.
|
// given store.
|
||||||
func (dao *dao) PutAppExecResult(aer *state.AppExecResult) error {
|
func (dao *simpleDao) PutAppExecResult(aer *state.AppExecResult) error {
|
||||||
key := storage.AppendPrefix(storage.STNotification, aer.TxHash.BytesBE())
|
key := storage.AppendPrefix(storage.STNotification, aer.TxHash.BytesBE())
|
||||||
return dao.Put(aer, key)
|
return dao.Put(aer, key)
|
||||||
}
|
}
|
||||||
|
@ -341,7 +405,7 @@ func (dao *dao) PutAppExecResult(aer *state.AppExecResult) error {
|
||||||
// -- start storage item.
|
// -- start storage item.
|
||||||
|
|
||||||
// GetStorageItem returns StorageItem if it exists in the given Store.
|
// GetStorageItem returns StorageItem if it exists in the given Store.
|
||||||
func (dao *dao) GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem {
|
func (dao *simpleDao) GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem {
|
||||||
b, err := dao.store.Get(makeStorageItemKey(scripthash, key))
|
b, err := dao.store.Get(makeStorageItemKey(scripthash, key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -359,18 +423,18 @@ func (dao *dao) GetStorageItem(scripthash util.Uint160, key []byte) *state.Stora
|
||||||
|
|
||||||
// PutStorageItem puts given StorageItem for given script with given
|
// PutStorageItem puts given StorageItem for given script with given
|
||||||
// key into the given Store.
|
// key into the given Store.
|
||||||
func (dao *dao) PutStorageItem(scripthash util.Uint160, key []byte, si *state.StorageItem) error {
|
func (dao *simpleDao) PutStorageItem(scripthash util.Uint160, key []byte, si *state.StorageItem) error {
|
||||||
return dao.Put(si, makeStorageItemKey(scripthash, key))
|
return dao.Put(si, makeStorageItemKey(scripthash, key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteStorageItem drops storage item for the given script with the
|
// DeleteStorageItem drops storage item for the given script with the
|
||||||
// given key from the Store.
|
// given key from the Store.
|
||||||
func (dao *dao) DeleteStorageItem(scripthash util.Uint160, key []byte) error {
|
func (dao *simpleDao) DeleteStorageItem(scripthash util.Uint160, key []byte) error {
|
||||||
return dao.store.Delete(makeStorageItemKey(scripthash, key))
|
return dao.store.Delete(makeStorageItemKey(scripthash, key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStorageItems returns all storage items for a given scripthash.
|
// GetStorageItems returns all storage items for a given scripthash.
|
||||||
func (dao *dao) GetStorageItems(hash util.Uint160) (map[string]*state.StorageItem, error) {
|
func (dao *simpleDao) GetStorageItems(hash util.Uint160) (map[string]*state.StorageItem, error) {
|
||||||
var siMap = make(map[string]*state.StorageItem)
|
var siMap = make(map[string]*state.StorageItem)
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -406,7 +470,7 @@ func makeStorageItemKey(scripthash util.Uint160, key []byte) []byte {
|
||||||
// -- other.
|
// -- other.
|
||||||
|
|
||||||
// GetBlock returns Block by the given hash if it exists in the store.
|
// GetBlock returns Block by the given hash if it exists in the store.
|
||||||
func (dao *dao) GetBlock(hash util.Uint256) (*block.Block, uint32, error) {
|
func (dao *simpleDao) GetBlock(hash util.Uint256) (*block.Block, uint32, error) {
|
||||||
key := storage.AppendPrefix(storage.DataBlock, hash.BytesLE())
|
key := storage.AppendPrefix(storage.DataBlock, hash.BytesLE())
|
||||||
b, err := dao.store.Get(key)
|
b, err := dao.store.Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -422,14 +486,14 @@ func (dao *dao) GetBlock(hash util.Uint256) (*block.Block, uint32, error) {
|
||||||
|
|
||||||
// GetVersion attempts to get the current version stored in the
|
// GetVersion attempts to get the current version stored in the
|
||||||
// underlying Store.
|
// underlying Store.
|
||||||
func (dao *dao) GetVersion() (string, error) {
|
func (dao *simpleDao) GetVersion() (string, error) {
|
||||||
version, err := dao.store.Get(storage.SYSVersion.Bytes())
|
version, err := dao.store.Get(storage.SYSVersion.Bytes())
|
||||||
return string(version), err
|
return string(version), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentBlockHeight returns the current block height found in the
|
// GetCurrentBlockHeight returns the current block height found in the
|
||||||
// underlying Store.
|
// underlying Store.
|
||||||
func (dao *dao) GetCurrentBlockHeight() (uint32, error) {
|
func (dao *simpleDao) GetCurrentBlockHeight() (uint32, error) {
|
||||||
b, err := dao.store.Get(storage.SYSCurrentBlock.Bytes())
|
b, err := dao.store.Get(storage.SYSCurrentBlock.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -439,7 +503,7 @@ func (dao *dao) GetCurrentBlockHeight() (uint32, error) {
|
||||||
|
|
||||||
// GetCurrentHeaderHeight returns the current header height and hash from
|
// GetCurrentHeaderHeight returns the current header height and hash from
|
||||||
// the underlying Store.
|
// the underlying Store.
|
||||||
func (dao *dao) GetCurrentHeaderHeight() (i uint32, h util.Uint256, err error) {
|
func (dao *simpleDao) GetCurrentHeaderHeight() (i uint32, h util.Uint256, err error) {
|
||||||
var b []byte
|
var b []byte
|
||||||
b, err = dao.store.Get(storage.SYSCurrentHeader.Bytes())
|
b, err = dao.store.Get(storage.SYSCurrentHeader.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -452,7 +516,7 @@ func (dao *dao) GetCurrentHeaderHeight() (i uint32, h util.Uint256, err error) {
|
||||||
|
|
||||||
// GetHeaderHashes returns a sorted list of header hashes retrieved from
|
// GetHeaderHashes returns a sorted list of header hashes retrieved from
|
||||||
// the given underlying Store.
|
// the given underlying Store.
|
||||||
func (dao *dao) GetHeaderHashes() ([]util.Uint256, error) {
|
func (dao *simpleDao) GetHeaderHashes() ([]util.Uint256, error) {
|
||||||
hashMap := make(map[uint32][]util.Uint256)
|
hashMap := make(map[uint32][]util.Uint256)
|
||||||
dao.store.Seek(storage.IXHeaderHashList.Bytes(), func(k, v []byte) {
|
dao.store.Seek(storage.IXHeaderHashList.Bytes(), func(k, v []byte) {
|
||||||
storedCount := binary.LittleEndian.Uint32(k[1:])
|
storedCount := binary.LittleEndian.Uint32(k[1:])
|
||||||
|
@ -482,7 +546,7 @@ func (dao *dao) GetHeaderHashes() ([]util.Uint256, error) {
|
||||||
|
|
||||||
// GetTransaction returns Transaction and its height by the given hash
|
// GetTransaction returns Transaction and its height by the given hash
|
||||||
// if it exists in the store.
|
// if it exists in the store.
|
||||||
func (dao *dao) GetTransaction(hash util.Uint256) (*transaction.Transaction, uint32, error) {
|
func (dao *simpleDao) GetTransaction(hash util.Uint256) (*transaction.Transaction, uint32, error) {
|
||||||
key := storage.AppendPrefix(storage.DataTransaction, hash.BytesLE())
|
key := storage.AppendPrefix(storage.DataTransaction, hash.BytesLE())
|
||||||
b, err := dao.store.Get(key)
|
b, err := dao.store.Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -502,12 +566,12 @@ func (dao *dao) GetTransaction(hash util.Uint256) (*transaction.Transaction, uin
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutVersion stores the given version in the underlying Store.
|
// PutVersion stores the given version in the underlying Store.
|
||||||
func (dao *dao) PutVersion(v string) error {
|
func (dao *simpleDao) PutVersion(v string) error {
|
||||||
return dao.store.Put(storage.SYSVersion.Bytes(), []byte(v))
|
return dao.store.Put(storage.SYSVersion.Bytes(), []byte(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutCurrentHeader stores current header.
|
// PutCurrentHeader stores current header.
|
||||||
func (dao *dao) PutCurrentHeader(hashAndIndex []byte) error {
|
func (dao *simpleDao) PutCurrentHeader(hashAndIndex []byte) error {
|
||||||
return dao.store.Put(storage.SYSCurrentHeader.Bytes(), hashAndIndex)
|
return dao.store.Put(storage.SYSCurrentHeader.Bytes(), hashAndIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,7 +590,7 @@ func read2000Uint256Hashes(b []byte) ([]util.Uint256, error) {
|
||||||
|
|
||||||
// HasTransaction returns true if the given store contains the given
|
// HasTransaction returns true if the given store contains the given
|
||||||
// Transaction hash.
|
// Transaction hash.
|
||||||
func (dao *dao) HasTransaction(hash util.Uint256) bool {
|
func (dao *simpleDao) HasTransaction(hash util.Uint256) bool {
|
||||||
key := storage.AppendPrefix(storage.DataTransaction, hash.BytesLE())
|
key := storage.AppendPrefix(storage.DataTransaction, hash.BytesLE())
|
||||||
if _, err := dao.store.Get(key); err == nil {
|
if _, err := dao.store.Get(key); err == nil {
|
||||||
return true
|
return true
|
||||||
|
@ -535,7 +599,7 @@ func (dao *dao) HasTransaction(hash util.Uint256) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreAsBlock stores the given block as DataBlock.
|
// StoreAsBlock stores the given block as DataBlock.
|
||||||
func (dao *dao) StoreAsBlock(block *block.Block, sysFee uint32) error {
|
func (dao *simpleDao) StoreAsBlock(block *block.Block, sysFee uint32) error {
|
||||||
var (
|
var (
|
||||||
key = storage.AppendPrefix(storage.DataBlock, block.Hash().BytesLE())
|
key = storage.AppendPrefix(storage.DataBlock, block.Hash().BytesLE())
|
||||||
buf = io.NewBufBinWriter()
|
buf = io.NewBufBinWriter()
|
||||||
|
@ -553,7 +617,7 @@ func (dao *dao) StoreAsBlock(block *block.Block, sysFee uint32) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreAsCurrentBlock stores the given block witch prefix SYSCurrentBlock.
|
// StoreAsCurrentBlock stores the given block witch prefix SYSCurrentBlock.
|
||||||
func (dao *dao) StoreAsCurrentBlock(block *block.Block) error {
|
func (dao *simpleDao) StoreAsCurrentBlock(block *block.Block) error {
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
h := block.Hash()
|
h := block.Hash()
|
||||||
h.EncodeBinary(buf.BinWriter)
|
h.EncodeBinary(buf.BinWriter)
|
||||||
|
@ -562,7 +626,7 @@ func (dao *dao) StoreAsCurrentBlock(block *block.Block) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreAsTransaction stores the given TX as DataTransaction.
|
// StoreAsTransaction stores the given TX as DataTransaction.
|
||||||
func (dao *dao) StoreAsTransaction(tx *transaction.Transaction, index uint32) error {
|
func (dao *simpleDao) StoreAsTransaction(tx *transaction.Transaction, index uint32) error {
|
||||||
key := storage.AppendPrefix(storage.DataTransaction, tx.Hash().BytesLE())
|
key := storage.AppendPrefix(storage.DataTransaction, tx.Hash().BytesLE())
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
buf.WriteU32LE(index)
|
buf.WriteU32LE(index)
|
||||||
|
@ -574,16 +638,16 @@ func (dao *dao) StoreAsTransaction(tx *transaction.Transaction, index uint32) er
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDoubleSpend verifies that the input transactions are not double spent.
|
// IsDoubleSpend verifies that the input transactions are not double spent.
|
||||||
func (dao *dao) IsDoubleSpend(tx *transaction.Transaction) bool {
|
func (dao *simpleDao) IsDoubleSpend(tx *transaction.Transaction) bool {
|
||||||
return dao.checkUsedInputs(tx.Inputs, state.CoinSpent)
|
return dao.checkUsedInputs(tx.Inputs, state.CoinSpent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDoubleClaim verifies that given claim inputs are not already claimed by another tx.
|
// IsDoubleClaim verifies that given claim inputs are not already claimed by another tx.
|
||||||
func (dao *dao) IsDoubleClaim(claim *transaction.ClaimTX) bool {
|
func (dao *simpleDao) IsDoubleClaim(claim *transaction.ClaimTX) bool {
|
||||||
return dao.checkUsedInputs(claim.Claims, state.CoinClaimed)
|
return dao.checkUsedInputs(claim.Claims, state.CoinClaimed)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dao *dao) checkUsedInputs(inputs []transaction.Input, coin state.Coin) bool {
|
func (dao *simpleDao) checkUsedInputs(inputs []transaction.Input, coin state.Coin) bool {
|
||||||
if len(inputs) == 0 {
|
if len(inputs) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -604,6 +668,6 @@ func (dao *dao) checkUsedInputs(inputs []transaction.Input, coin state.Coin) boo
|
||||||
|
|
||||||
// Persist flushes all the changes made into the (supposedly) persistent
|
// Persist flushes all the changes made into the (supposedly) persistent
|
||||||
// underlying store.
|
// underlying store.
|
||||||
func (dao *dao) Persist() (int, error) {
|
func (dao *simpleDao) Persist() (int, error) {
|
||||||
return dao.store.Persist()
|
return dao.store.Persist()
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPutGetAndDecode(t *testing.T) {
|
func TestPutGetAndDecode(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
serializable := &TestSerializable{field: random.String(4)}
|
serializable := &TestSerializable{field: random.String(4)}
|
||||||
hash := []byte{1}
|
hash := []byte{1}
|
||||||
err := dao.Put(serializable, hash)
|
err := dao.Put(serializable, hash)
|
||||||
|
@ -41,7 +41,7 @@ func (t *TestSerializable) DecodeBinary(reader *io.BinReader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetAccountStateOrNew_New(t *testing.T) {
|
func TestGetAccountStateOrNew_New(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
hash := random.Uint160()
|
hash := random.Uint160()
|
||||||
createdAccount, err := dao.GetAccountStateOrNew(hash)
|
createdAccount, err := dao.GetAccountStateOrNew(hash)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -49,7 +49,7 @@ func TestGetAccountStateOrNew_New(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutAndGetAccountStateOrNew(t *testing.T) {
|
func TestPutAndGetAccountStateOrNew(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
hash := random.Uint160()
|
hash := random.Uint160()
|
||||||
accountState := &state.Account{ScriptHash: hash}
|
accountState := &state.Account{ScriptHash: hash}
|
||||||
err := dao.PutAccountState(accountState)
|
err := dao.PutAccountState(accountState)
|
||||||
|
@ -60,7 +60,7 @@ func TestPutAndGetAccountStateOrNew(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutAndGetAssetState(t *testing.T) {
|
func TestPutAndGetAssetState(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
id := random.Uint256()
|
id := random.Uint256()
|
||||||
assetState := &state.Asset{ID: id, Owner: keys.PublicKey{}}
|
assetState := &state.Asset{ID: id, Owner: keys.PublicKey{}}
|
||||||
err := dao.PutAssetState(assetState)
|
err := dao.PutAssetState(assetState)
|
||||||
|
@ -71,7 +71,7 @@ func TestPutAndGetAssetState(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutAndGetContractState(t *testing.T) {
|
func TestPutAndGetContractState(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
contractState := &state.Contract{Script: []byte{}, ParamList: []smartcontract.ParamType{}}
|
contractState := &state.Contract{Script: []byte{}, ParamList: []smartcontract.ParamType{}}
|
||||||
hash := contractState.ScriptHash()
|
hash := contractState.ScriptHash()
|
||||||
err := dao.PutContractState(contractState)
|
err := dao.PutContractState(contractState)
|
||||||
|
@ -82,7 +82,7 @@ func TestPutAndGetContractState(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteContractState(t *testing.T) {
|
func TestDeleteContractState(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
contractState := &state.Contract{Script: []byte{}, ParamList: []smartcontract.ParamType{}}
|
contractState := &state.Contract{Script: []byte{}, ParamList: []smartcontract.ParamType{}}
|
||||||
hash := contractState.ScriptHash()
|
hash := contractState.ScriptHash()
|
||||||
err := dao.PutContractState(contractState)
|
err := dao.PutContractState(contractState)
|
||||||
|
@ -95,7 +95,7 @@ func TestDeleteContractState(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetUnspentCoinState_Err(t *testing.T) {
|
func TestGetUnspentCoinState_Err(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
hash := random.Uint256()
|
hash := random.Uint256()
|
||||||
gotUnspentCoinState, err := dao.GetUnspentCoinState(hash)
|
gotUnspentCoinState, err := dao.GetUnspentCoinState(hash)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
@ -103,7 +103,7 @@ func TestGetUnspentCoinState_Err(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutGetUnspentCoinState(t *testing.T) {
|
func TestPutGetUnspentCoinState(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
hash := random.Uint256()
|
hash := random.Uint256()
|
||||||
unspentCoinState := &state.UnspentCoin{Height: 42, States: []state.OutputState{}}
|
unspentCoinState := &state.UnspentCoin{Height: 42, States: []state.OutputState{}}
|
||||||
err := dao.PutUnspentCoinState(hash, unspentCoinState)
|
err := dao.PutUnspentCoinState(hash, unspentCoinState)
|
||||||
|
@ -114,7 +114,7 @@ func TestPutGetUnspentCoinState(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetValidatorStateOrNew_New(t *testing.T) {
|
func TestGetValidatorStateOrNew_New(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
publicKey := &keys.PublicKey{}
|
publicKey := &keys.PublicKey{}
|
||||||
validatorState, err := dao.GetValidatorStateOrNew(publicKey)
|
validatorState, err := dao.GetValidatorStateOrNew(publicKey)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -122,7 +122,7 @@ func TestGetValidatorStateOrNew_New(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutGetValidatorState(t *testing.T) {
|
func TestPutGetValidatorState(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
publicKey := &keys.PublicKey{}
|
publicKey := &keys.PublicKey{}
|
||||||
validatorState := &state.Validator{
|
validatorState := &state.Validator{
|
||||||
PublicKey: publicKey,
|
PublicKey: publicKey,
|
||||||
|
@ -137,7 +137,7 @@ func TestPutGetValidatorState(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteValidatorState(t *testing.T) {
|
func TestDeleteValidatorState(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
publicKey := &keys.PublicKey{}
|
publicKey := &keys.PublicKey{}
|
||||||
validatorState := &state.Validator{
|
validatorState := &state.Validator{
|
||||||
PublicKey: publicKey,
|
PublicKey: publicKey,
|
||||||
|
@ -154,7 +154,7 @@ func TestDeleteValidatorState(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetValidators(t *testing.T) {
|
func TestGetValidators(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
publicKey := &keys.PublicKey{}
|
publicKey := &keys.PublicKey{}
|
||||||
validatorState := &state.Validator{
|
validatorState := &state.Validator{
|
||||||
PublicKey: publicKey,
|
PublicKey: publicKey,
|
||||||
|
@ -169,7 +169,7 @@ func TestGetValidators(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutGetAppExecResult(t *testing.T) {
|
func TestPutGetAppExecResult(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
hash := random.Uint256()
|
hash := random.Uint256()
|
||||||
appExecResult := &state.AppExecResult{
|
appExecResult := &state.AppExecResult{
|
||||||
TxHash: hash,
|
TxHash: hash,
|
||||||
|
@ -184,7 +184,7 @@ func TestPutGetAppExecResult(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutGetStorageItem(t *testing.T) {
|
func TestPutGetStorageItem(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
hash := random.Uint160()
|
hash := random.Uint160()
|
||||||
key := []byte{0}
|
key := []byte{0}
|
||||||
storageItem := &state.StorageItem{Value: []uint8{}}
|
storageItem := &state.StorageItem{Value: []uint8{}}
|
||||||
|
@ -195,7 +195,7 @@ func TestPutGetStorageItem(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteStorageItem(t *testing.T) {
|
func TestDeleteStorageItem(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
hash := random.Uint160()
|
hash := random.Uint160()
|
||||||
key := []byte{0}
|
key := []byte{0}
|
||||||
storageItem := &state.StorageItem{Value: []uint8{}}
|
storageItem := &state.StorageItem{Value: []uint8{}}
|
||||||
|
@ -208,7 +208,7 @@ func TestDeleteStorageItem(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetBlock_NotExists(t *testing.T) {
|
func TestGetBlock_NotExists(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
hash := random.Uint256()
|
hash := random.Uint256()
|
||||||
block, _, err := dao.GetBlock(hash)
|
block, _, err := dao.GetBlock(hash)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
@ -216,7 +216,7 @@ func TestGetBlock_NotExists(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutGetBlock(t *testing.T) {
|
func TestPutGetBlock(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
b := &block.Block{
|
b := &block.Block{
|
||||||
Base: block.Base{
|
Base: block.Base{
|
||||||
Script: transaction.Witness{
|
Script: transaction.Witness{
|
||||||
|
@ -235,14 +235,14 @@ func TestPutGetBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetVersion_NoVersion(t *testing.T) {
|
func TestGetVersion_NoVersion(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
version, err := dao.GetVersion()
|
version, err := dao.GetVersion()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Equal(t, "", version)
|
require.Equal(t, "", version)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetVersion(t *testing.T) {
|
func TestGetVersion(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
err := dao.PutVersion("testVersion")
|
err := dao.PutVersion("testVersion")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
version, err := dao.GetVersion()
|
version, err := dao.GetVersion()
|
||||||
|
@ -251,14 +251,14 @@ func TestGetVersion(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) {
|
func TestGetCurrentHeaderHeight_NoHeader(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
height, err := dao.GetCurrentBlockHeight()
|
height, err := dao.GetCurrentBlockHeight()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
require.Equal(t, uint32(0), height)
|
require.Equal(t, uint32(0), height)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetCurrentHeaderHeight_Store(t *testing.T) {
|
func TestGetCurrentHeaderHeight_Store(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
b := &block.Block{
|
b := &block.Block{
|
||||||
Base: block.Base{
|
Base: block.Base{
|
||||||
Script: transaction.Witness{
|
Script: transaction.Witness{
|
||||||
|
@ -275,7 +275,7 @@ func TestGetCurrentHeaderHeight_Store(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStoreAsTransaction(t *testing.T) {
|
func TestStoreAsTransaction(t *testing.T) {
|
||||||
dao := newDao(storage.NewMemoryStore())
|
dao := newSimpleDao(storage.NewMemoryStore())
|
||||||
tx := &transaction.Transaction{Type: transaction.IssueType, Data: &transaction.IssueTX{}}
|
tx := &transaction.Transaction{Type: transaction.IssueType, Data: &transaction.IssueTX{}}
|
||||||
hash := tx.Hash()
|
hash := tx.Hash()
|
||||||
err := dao.StoreAsTransaction(tx, 0)
|
err := dao.StoreAsTransaction(tx, 0)
|
||||||
|
|
|
@ -15,7 +15,8 @@ import (
|
||||||
func TestGetPrice(t *testing.T) {
|
func TestGetPrice(t *testing.T) {
|
||||||
bc := newTestChain(t)
|
bc := newTestChain(t)
|
||||||
defer bc.Close()
|
defer bc.Close()
|
||||||
systemInterop := bc.newInteropContext(trigger.Application, storage.NewMemoryStore(), nil, nil)
|
sdao := newSimpleDao(storage.NewMemoryStore())
|
||||||
|
systemInterop := bc.newInteropContext(trigger.Application, sdao, nil, nil)
|
||||||
|
|
||||||
v := bc.spawnVMWithInterops(systemInterop)
|
v := bc.spawnVMWithInterops(systemInterop)
|
||||||
v.SetPriceGetter(getPrice)
|
v.SetPriceGetter(getPrice)
|
||||||
|
|
|
@ -123,7 +123,7 @@ func TestHeaderGetVersion_Negative(t *testing.T) {
|
||||||
block := newDumbBlock()
|
block := newDumbBlock()
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
defer chain.Close()
|
defer chain.Close()
|
||||||
context := chain.newInteropContext(trigger.Application, storage.NewMemoryStore(), block, nil)
|
context := chain.newInteropContext(trigger.Application, newSimpleDao(storage.NewMemoryStore()), block, nil)
|
||||||
v.Estack().PushVal(vm.NewBoolItem(false))
|
v.Estack().PushVal(vm.NewBoolItem(false))
|
||||||
|
|
||||||
err := context.headerGetVersion(v)
|
err := context.headerGetVersion(v)
|
||||||
|
@ -219,7 +219,7 @@ func TestWitnessGetVerificationScript(t *testing.T) {
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
defer chain.Close()
|
defer chain.Close()
|
||||||
|
|
||||||
context := chain.newInteropContext(trigger.Application, storage.NewMemoryStore(), nil, nil)
|
context := chain.newInteropContext(trigger.Application, newSimpleDao(storage.NewMemoryStore()), nil, nil)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(&witness))
|
v.Estack().PushVal(vm.NewInteropItem(&witness))
|
||||||
err := context.witnessGetVerificationScript(v)
|
err := context.witnessGetVerificationScript(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -462,7 +462,7 @@ func createVMAndPushBlock(t *testing.T) (*vm.VM, *block.Block, *interopContext,
|
||||||
v := vm.New()
|
v := vm.New()
|
||||||
block := newDumbBlock()
|
block := newDumbBlock()
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
context := chain.newInteropContext(trigger.Application, storage.NewMemoryStore(), block, nil)
|
context := chain.newInteropContext(trigger.Application, newSimpleDao(storage.NewMemoryStore()), block, nil)
|
||||||
v.Estack().PushVal(vm.NewInteropItem(block))
|
v.Estack().PushVal(vm.NewInteropItem(block))
|
||||||
return v, block, context, chain
|
return v, block, context, chain
|
||||||
}
|
}
|
||||||
|
@ -492,7 +492,7 @@ func createVMAndAssetState(t *testing.T) (*vm.VM, *state.Asset, *interopContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
context := chain.newInteropContext(trigger.Application, storage.NewMemoryStore(), nil, nil)
|
context := chain.newInteropContext(trigger.Application, newSimpleDao(storage.NewMemoryStore()), nil, nil)
|
||||||
return v, assetState, context, chain
|
return v, assetState, context, chain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +511,7 @@ func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interopCo
|
||||||
}
|
}
|
||||||
|
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
context := chain.newInteropContext(trigger.Application, storage.NewMemoryStore(), nil, nil)
|
context := chain.newInteropContext(trigger.Application, newSimpleDao(storage.NewMemoryStore()), nil, nil)
|
||||||
return v, contractState, context, chain
|
return v, contractState, context, chain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,7 +526,7 @@ func createVMAndAccState(t *testing.T) (*vm.VM, *state.Account, *interopContext,
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
context := chain.newInteropContext(trigger.Application, storage.NewMemoryStore(), nil, nil)
|
context := chain.newInteropContext(trigger.Application, newSimpleDao(storage.NewMemoryStore()), nil, nil)
|
||||||
return v, accountState, context, chain
|
return v, accountState, context, chain
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,6 +557,6 @@ func createVMAndTX(t *testing.T) (*vm.VM, *transaction.Transaction, *interopCont
|
||||||
tx.Inputs = inputs
|
tx.Inputs = inputs
|
||||||
tx.Outputs = outputs
|
tx.Outputs = outputs
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
context := chain.newInteropContext(trigger.Application, storage.NewMemoryStore(), nil, tx)
|
context := chain.newInteropContext(trigger.Application, newSimpleDao(storage.NewMemoryStore()), nil, tx)
|
||||||
return v, tx, context, chain
|
return v, tx, context, chain
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
|
@ -29,8 +28,8 @@ type interopContext struct {
|
||||||
log *zap.Logger
|
log *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInteropContext(trigger trigger.Type, bc Blockchainer, s storage.Store, block *block.Block, tx *transaction.Transaction, log *zap.Logger) *interopContext {
|
func newInteropContext(trigger trigger.Type, bc Blockchainer, d dao, block *block.Block, tx *transaction.Transaction, log *zap.Logger) *interopContext {
|
||||||
dao := newCachedDao(s)
|
dao := newCachedDao(d)
|
||||||
nes := make([]state.NotificationEvent, 0)
|
nes := make([]state.NotificationEvent, 0)
|
||||||
return &interopContext{bc, trigger, block, tx, dao, nes, log}
|
return &interopContext{bc, trigger, block, tx, dao, nes, log}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ func testNonInterop(t *testing.T, value interface{}, f func(*interopContext, *vm
|
||||||
v.Estack().PushVal(value)
|
v.Estack().PushVal(value)
|
||||||
chain := newTestChain(t)
|
chain := newTestChain(t)
|
||||||
defer chain.Close()
|
defer chain.Close()
|
||||||
context := chain.newInteropContext(trigger.Application, storage.NewMemoryStore(), nil, nil)
|
context := chain.newInteropContext(trigger.Application, newSimpleDao(storage.NewMemoryStore()), nil, nil)
|
||||||
require.Error(t, f(context, v))
|
require.Error(t, f(context, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
@ -109,7 +108,7 @@ func (chain testChain) GetScriptHashesForVerifying(*transaction.Transaction) ([]
|
||||||
func (chain testChain) GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem {
|
func (chain testChain) GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
func (chain testChain) GetTestVM() (*vm.VM, storage.Store) {
|
func (chain testChain) GetTestVM() *vm.VM {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
func (chain testChain) GetStorageItems(hash util.Uint160) (map[string]*state.StorageItem, error) {
|
func (chain testChain) GetStorageItems(hash util.Uint160) (map[string]*state.StorageItem, error) {
|
||||||
|
|
|
@ -881,7 +881,7 @@ func (s *Server) invokescript(reqParams request.Params) (interface{}, error) {
|
||||||
// runScriptInVM runs given script in a new test VM and returns the invocation
|
// runScriptInVM runs given script in a new test VM and returns the invocation
|
||||||
// result.
|
// result.
|
||||||
func (s *Server) runScriptInVM(script []byte) *result.Invoke {
|
func (s *Server) runScriptInVM(script []byte) *result.Invoke {
|
||||||
vm, _ := s.chain.GetTestVM()
|
vm := s.chain.GetTestVM()
|
||||||
vm.SetGasLimit(s.config.MaxGasInvoke)
|
vm.SetGasLimit(s.config.MaxGasInvoke)
|
||||||
vm.LoadScript(script)
|
vm.LoadScript(script)
|
||||||
_ = vm.Run()
|
_ = vm.Run()
|
||||||
|
|
Loading…
Reference in a new issue