func (ledger *Ledger) GetTempStateHash() ([]byte, error) {
	return ledger.state.GetHash()
}
///////////////// world-state related methods /////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
GetTempStateHash - Computes state hash by taking into account the state changes that may have taken
place during the execution of current transaction-batch
package ledger
import (
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"sync"
	"github.com/golang/protobuf/proto"
	"github.com/op/go-logging"
	"github.com/openblockchain/obc-peer/events/producer"
	"github.com/openblockchain/obc-peer/openchain/db"
	"github.com/openblockchain/obc-peer/openchain/ledger/statemgmt"
	"github.com/openblockchain/obc-peer/openchain/ledger/statemgmt/state"
	"github.com/tecbot/gorocksdb"
	"github.com/openblockchain/obc-peer/protos"
	"golang.org/x/net/context"
)
var ledgerLogger = logging.MustGetLogger("ledger")
var (
	ErrOutOfBounds = errors.New("ledger: out of bounds")
	ErrResourceNotFound = errors.New("ledger: resource not found")
)
type Ledger struct {
	blockchain *blockchain
	state      *state.State
	currentID  interface{}
}
var ledger *Ledger
var ledgerError error
var once sync.Once
func GetLedger() (*Ledger, error) {
	once.Do(func() {
		ledger, ledgerError = newLedger()
	})
	return ledger, ledgerError
}
func newLedger() (*Ledger, error) {
	blockchain, err := newBlockchain()
	if err != nil {
		return nil, err
	}
	state := state.NewState()
	return &Ledger{blockchain, state, nil}, nil
}
func (ledger *Ledger) BeginTxBatch(id interface{}) error {
	err := ledger.checkValidIDBegin()
	if err != nil {
		return err
	}
	ledger.currentID = id
	return nil
}
func (ledger *Ledger) GetTXBatchPreviewBlock(id interface{},
	transactions []*protos.Transaction, metadata []byte) (*protos.Block, error) {
	err := ledger.checkValidIDCommitORRollback(id)
	if err != nil {
		return nil, err
	}
	stateHash, err := ledger.state.GetHash()
	if err != nil {
		return nil, err
	}
	return ledger.blockchain.buildBlock(protos.NewBlock(transactions, metadata), stateHash), nil
}
func (ledger *Ledger) CommitTxBatch(id interface{}, transactions []*protos.Transaction, transactionResults []*protos.TransactionResult, metadata []byte) error {
	err := ledger.checkValidIDCommitORRollback(id)
	if err != nil {
		return err
	}
	stateHash, err := ledger.state.GetHash()
	if err != nil {
		ledger.resetForNextTxGroup(false)
		ledger.blockchain.blockPersistenceStatus(false)
		return err
	}
	writeBatch := gorocksdb.NewWriteBatch()
	defer writeBatch.Destroy()
	block := protos.NewBlock(transactions, metadata)
	block.NonHashData = &protos.NonHashData{TransactionResults: transactionResults}
	newBlockNumber, err := ledger.blockchain.addPersistenceChangesForNewBlock(context.TODO(), block, stateHash, writeBatch)
	if err != nil {
		ledger.resetForNextTxGroup(false)
		ledger.blockchain.blockPersistenceStatus(false)
		return err
	}
	ledger.state.AddChangesForPersistence(newBlockNumber, writeBatch)
	opt := gorocksdb.NewDefaultWriteOptions()
	defer opt.Destroy()
	dbErr := db.GetDBHandle().DB.Write(opt, writeBatch)
	if dbErr != nil {
		ledger.resetForNextTxGroup(false)
		ledger.blockchain.blockPersistenceStatus(false)
		return dbErr
	}
	ledger.resetForNextTxGroup(true)
	ledger.blockchain.blockPersistenceStatus(true)
	sendProducerBlockEvent(block)
	return nil
}
func (ledger *Ledger) RollbackTxBatch(id interface{}) error {
	ledgerLogger.Debug("RollbackTxBatch for id = [%s]", id)
	err := ledger.checkValidIDCommitORRollback(id)
	if err != nil {
		return err
	}
	ledger.resetForNextTxGroup(false)
	return nil
}
func (ledger *Ledger) TxBegin(txUUID string) {
	ledger.state.TxBegin(txUUID)
}
func (ledger *Ledger) TxFinished(txUUID string, txSuccessful bool) {
	ledger.state.TxFinish(txUUID, txSuccessful)
}