2019-11-18 10:58:32 +00:00
|
|
|
package core
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
|
|
|
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
|
|
|
"github.com/CityOfZion/neo-go/pkg/io"
|
|
|
|
)
|
|
|
|
|
|
|
|
// BlockChainState represents Blockchain state structure with mempool.
|
|
|
|
type BlockChainState struct {
|
|
|
|
store *storage.MemCachedStore
|
|
|
|
unspentCoins UnspentCoins
|
|
|
|
spentCoins SpentCoins
|
|
|
|
accounts Accounts
|
|
|
|
assets Assets
|
|
|
|
contracts Contracts
|
|
|
|
validators Validators
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewBlockChainState creates blockchain state with it's memchached store.
|
|
|
|
func NewBlockChainState(store *storage.MemCachedStore) *BlockChainState {
|
2019-11-27 10:28:13 +00:00
|
|
|
tmpStore := storage.NewMemCachedStore(store)
|
2019-11-18 10:58:32 +00:00
|
|
|
return &BlockChainState{
|
2019-11-27 10:28:13 +00:00
|
|
|
store: tmpStore,
|
2019-11-18 10:58:32 +00:00
|
|
|
unspentCoins: make(UnspentCoins),
|
|
|
|
spentCoins: make(SpentCoins),
|
|
|
|
accounts: make(Accounts),
|
|
|
|
assets: make(Assets),
|
|
|
|
contracts: make(Contracts),
|
|
|
|
validators: make(Validators),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// commit commits all the data in current state into storage.
|
2019-11-27 10:27:47 +00:00
|
|
|
func (state *BlockChainState) commit() error {
|
2019-11-18 10:58:32 +00:00
|
|
|
if err := state.accounts.commit(state.store); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := state.unspentCoins.commit(state.store); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := state.spentCoins.commit(state.store); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := state.assets.commit(state.store); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := state.contracts.commit(state.store); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := state.validators.commit(state.store); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if _, err := state.store.Persist(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// storeAsBlock stores the given block as DataBlock.
|
|
|
|
func (state *BlockChainState) storeAsBlock(block *Block, sysFee uint32) error {
|
|
|
|
var (
|
2019-11-27 09:23:18 +00:00
|
|
|
key = storage.AppendPrefix(storage.DataBlock, block.Hash().BytesLE())
|
2019-11-18 10:58:32 +00:00
|
|
|
buf = io.NewBufBinWriter()
|
|
|
|
)
|
|
|
|
// sysFee needs to be handled somehow
|
|
|
|
// buf.WriteLE(sysFee)
|
|
|
|
b, err := block.Trim()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-11-22 10:34:06 +00:00
|
|
|
buf.WriteBytes(b)
|
2019-11-18 10:58:32 +00:00
|
|
|
if buf.Err != nil {
|
|
|
|
return buf.Err
|
|
|
|
}
|
|
|
|
return state.store.Put(key, buf.Bytes())
|
|
|
|
}
|
|
|
|
|
|
|
|
// storeAsCurrentBlock stores the given block witch prefix SYSCurrentBlock.
|
|
|
|
func (state *BlockChainState) storeAsCurrentBlock(block *Block) error {
|
|
|
|
buf := io.NewBufBinWriter()
|
2019-11-27 09:23:18 +00:00
|
|
|
buf.WriteBytes(block.Hash().BytesLE())
|
2019-11-18 10:58:32 +00:00
|
|
|
buf.WriteLE(block.Index)
|
|
|
|
return state.store.Put(storage.SYSCurrentBlock.Bytes(), buf.Bytes())
|
|
|
|
}
|
|
|
|
|
|
|
|
// storeAsTransaction stores the given TX as DataTransaction.
|
|
|
|
func (state *BlockChainState) storeAsTransaction(tx *transaction.Transaction, index uint32) error {
|
2019-11-27 09:23:18 +00:00
|
|
|
key := storage.AppendPrefix(storage.DataTransaction, tx.Hash().BytesLE())
|
2019-11-18 10:58:32 +00:00
|
|
|
buf := io.NewBufBinWriter()
|
|
|
|
buf.WriteLE(index)
|
|
|
|
tx.EncodeBinary(buf.BinWriter)
|
|
|
|
if buf.Err != nil {
|
|
|
|
return buf.Err
|
|
|
|
}
|
|
|
|
return state.store.Put(key, buf.Bytes())
|
|
|
|
}
|