forked from TrueCloudLab/neoneo-go
467c9c146d
Commit c80ee952a1
removed temporary store used
to contain changes of the block being processed. It's wrong in that the block
changes should be applied to the database in a single transaction so that
there wouldn't be any intermediate state observed from the outside (which is
possible now). Also, this made changes commiting persist them to the
underlying store effectively making our persist loop a no-op (and not
producing `persist completed` log lines that we love so much).
97 lines
2.7 KiB
Go
97 lines
2.7 KiB
Go
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 {
|
|
tmpStore := storage.NewMemCachedStore(store)
|
|
return &BlockChainState{
|
|
store: tmpStore,
|
|
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.
|
|
func (state *BlockChainState) commit() error {
|
|
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 (
|
|
key = storage.AppendPrefix(storage.DataBlock, block.Hash().BytesReverse())
|
|
buf = io.NewBufBinWriter()
|
|
)
|
|
// sysFee needs to be handled somehow
|
|
// buf.WriteLE(sysFee)
|
|
b, err := block.Trim()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
buf.WriteLE(b)
|
|
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()
|
|
buf.WriteLE(block.Hash().BytesReverse())
|
|
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 {
|
|
key := storage.AppendPrefix(storage.DataTransaction, tx.Hash().BytesReverse())
|
|
buf := io.NewBufBinWriter()
|
|
buf.WriteLE(index)
|
|
tx.EncodeBinary(buf.BinWriter)
|
|
if buf.Err != nil {
|
|
return buf.Err
|
|
}
|
|
return state.store.Put(key, buf.Bytes())
|
|
}
|