github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/mainchain/storages/ledger_store.go (about)

     1  package storages
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"sync"
     7  
     8  	"path"
     9  
    10  	"github.com/sixexorg/magnetic-ring/bactor"
    11  	"github.com/sixexorg/magnetic-ring/log"
    12  
    13  	"github.com/sixexorg/magnetic-ring/common"
    14  	"github.com/sixexorg/magnetic-ring/core/mainchain/types"
    15  	"github.com/sixexorg/magnetic-ring/store/mainchain/account_level"
    16  	"github.com/sixexorg/magnetic-ring/store/mainchain/actor"
    17  	"github.com/sixexorg/magnetic-ring/store/mainchain/states"
    18  	//scom "github.com/sixexorg/magnetic-ring/store/mainchain/common"
    19  	"encoding/binary"
    20  	"github.com/sixexorg/magnetic-ring/node"
    21  	"github.com/sixexorg/magnetic-ring/config"
    22  )
    23  
    24  const (
    25  	SYSTEM_VERSION          = byte(1)      //Version of ledger store
    26  	HEADER_INDEX_BATCH_SIZE = uint64(2000) //Bath size of saving header index
    27  	cycle                   = int(1)
    28  )
    29  
    30  var (
    31  	//Storage save path.
    32  	DBDirBlock          = "block"
    33  	DBDirState          = "states"
    34  	DBDirLeague         = "league"
    35  	DBDirMember         = "member"
    36  	DBDirBirthCert      = "birth"
    37  	DBDirReceipt        = "receipt"
    38  	DBDirLvl            = "lvl"
    39  	MerkleTreeStorePath = "merkle_tree.db"
    40  )
    41  
    42  //LedgerStoreImp is main store struct fo ledger
    43  type LedgerStoreImp struct {
    44  	blockStore *BlockStore //BlockStore for saving block & transaction data
    45  	//stateStore *StateStore //StateStore for saving state data, like balance, smart contract execution result, and so on.
    46  	lvlManager     *account_level.LevelManager
    47  	accountStore   *AccountStore // Latest balance
    48  	leagueStore    *LeagueStore  // How many funds are frozen in the circle, creating circles, issuing additional operations, etc.
    49  	memberStore    *MemberStore  // User status on the main chain
    50  	birthCertStore *LeagueBirthCertStore  // Org trading
    51  	receiptStore   *ReceiptStore  // Transaction receipt
    52  
    53  	storedIndexCount uint64                        //record the count of have saved block index
    54  	currBlockHeight  uint64                        //Current block height                                1
    55  	currBlockHash    common.Hash                   //Current block hash                                  1
    56  	headerCache      map[common.Hash]*types.Header //BlockHash => Header
    57  	headerIndex      map[uint64]common.Hash        //Header index, Mapping header height => block hash
    58  	savingBlock      bool                          //is saving block now
    59  
    60  	bonusCache map[uint64][]uint64
    61  	lock       sync.RWMutex
    62  }
    63  
    64  var ledgerStore *LedgerStoreImp
    65  
    66  func (this *LedgerStoreImp) GetAccountStore() *AccountStore {
    67  	return this.accountStore
    68  }
    69  
    70  func GetLedgerStore() *LedgerStoreImp {
    71  	/*	if ledgerStore == nil {
    72  		return nil, errors.ERR_SETUP_MAIN_LEDGER_UNINITIALIZED
    73  	}*/
    74  	return ledgerStore
    75  }
    76  
    77  //NewLedgerStore return LedgerStoreImp instance
    78  func NewLedgerStore(dataDir string) (*LedgerStoreImp, error) {
    79  	if ledgerStore != nil {
    80  		return ledgerStore, nil
    81  	}
    82  
    83  	ledgerStore = &LedgerStoreImp{
    84  		headerIndex: make(map[uint64]common.Hash),
    85  		headerCache: make(map[common.Hash]*types.Header, 0),
    86  		bonusCache:  make(map[uint64][]uint64),
    87  	}
    88  	blockStore, err := NewBlockStore(path.Join(dataDir, DBDirBlock), true)
    89  	if err != nil {
    90  		return nil, fmt.Errorf("NewBlockStore error %s", err)
    91  	}
    92  	ledgerStore.blockStore = blockStore
    93  
    94  	accountStore, err := NewAccoutStore(path.Join(dataDir, DBDirState), false)
    95  	if err != nil {
    96  		fmt.Fprintf(os.Stderr, "NewAccoutStore error %s\n", err)
    97  		return nil, err
    98  	}
    99  
   100  	ledgerStore.accountStore = accountStore
   101  
   102  	leagueStore, err := NewLeagueStore(path.Join(dataDir, DBDirLeague))
   103  	if err != nil {
   104  		return nil, fmt.Errorf("NewLeagueStore error %s", err)
   105  	}
   106  	ledgerStore.leagueStore = leagueStore
   107  
   108  	memberStore, err := NewMemberStore(path.Join(dataDir, DBDirMember))
   109  	if err != nil {
   110  		return nil, fmt.Errorf("NewMemberStore error %s", err)
   111  	}
   112  	ledgerStore.memberStore = memberStore
   113  
   114  	birthStore, err := NewLeagueBirthCertStore(path.Join(dataDir, DBDirBirthCert))
   115  	if err != nil {
   116  		return nil, fmt.Errorf("NewMemberStore error %s", err)
   117  	}
   118  	ledgerStore.birthCertStore = birthStore
   119  	receiptStore, err := NewReceiptStore(path.Join(dataDir, DBDirReceipt), false)
   120  	if err != nil {
   121  		return nil, fmt.Errorf("NewReceiptStore error %s", err)
   122  	}
   123  	ledgerStore.receiptStore = receiptStore
   124  	/*stateStore, err := NewStateStore(fmt.Sprintf("%s%s%s", dataDir, string(os.PathSeparator), DBDirState),
   125  		fmt.Sprintf("%s%s%s", dataDir, string(os.PathSeparator), MerkleTreeStorePath))
   126  	if err != nil {
   127  		return nil, fmt.Errorf("NewStateStore error %s", err)
   128  	}
   129  	ledgerStore.stateStore = stateStore*/
   130  
   131  	/*lvlManager, err := account_level.NewLevelManager(cycle, types.HWidth, path.Join(dataDir, DBDirLvl))
   132  	if err != nil {
   133  		return nil, fmt.Errorf("NewLevelManager error %s", err)
   134  	}
   135  	ledgerStore.lvlManager = lvlManager*/
   136  	ledgerStore.restoreVars()
   137  
   138  	return ledgerStore, nil
   139  }
   140  
   141  func (this *LedgerStoreImp) RestoreVars() {
   142  	this.restoreVars()
   143  }
   144  
   145  func (this *LedgerStoreImp) restoreVars() {
   146  	//this.currBlockHash, this.currBlockHeight, _ = this.blockStore.GetCurrentBlock()
   147  	//this.blockStore.GetCurrentBlock()
   148  	var err error
   149  	var blk *types.Block
   150  	prefix := make([]byte, 1, 1)
   151  	prefix[0] = 0x00
   152  	iter := this.blockStore.store.NewIterator(prefix)
   153  	if iter.Last() {
   154  		key := iter.Key()
   155  		this.currBlockHeight = binary.LittleEndian.Uint64(key[1:])
   156  		value := iter.Value() //hash
   157  		this.currBlockHash, err = common.ParseHashFromBytes(value)
   158  		if err != nil {
   159  			return
   160  		}
   161  		blk, _ = this.GetBlockByHash(this.currBlockHash)
   162  	}
   163  	this.storedIndexCount = this.currBlockHeight
   164  	log.Info("LedgerStoreImp restoreVars currBlockHash:%v, currBlockHeight:%v, .storedIndexCount:%v",
   165  		this.currBlockHash.String(), this.currBlockHeight, this.storedIndexCount)
   166  	fmt.Println("------=========:", this.currBlockHash, this.currBlockHeight, this.storedIndexCount)
   167  
   168  
   169  	if this.currBlockHeight > 1{
   170  		stars := make([]string, 0, len(config.GlobalConfig.Genesis.Stars))
   171  		for _, star := range config.GlobalConfig.Genesis.Stars{
   172  			stars = append(stars, star.Nodekey)
   173  		}
   174  		node.PushStars(stars)
   175  	}
   176  
   177  	if actor.ConsensusPid != nil {
   178  		fmt.Println()
   179  		actor.ConsensusPid.Tell(blk)
   180  	}
   181  
   182  	//txpoolPid, err := bactor.GetActorPid(bactor.TXPOOLACTOR)
   183  	//
   184  	//if err != nil {
   185  	//	log.Error("txpoolactor not found")
   186  	//} else {
   187  	//	if blockInfo.Block.Header.Height > 1 {
   188  	//		hi := bactor.HeightChange{blockInfo.Height()}
   189  	//		txpoolPid.Tell(hi)
   190  	//	}
   191  	//}
   192  
   193  	radarActor, err := bactor.GetActorPid(bactor.MAINRADARACTOR)
   194  	if err != nil {
   195  		log.Error("radarActor not found")
   196  	} else {
   197  		radarActor.Tell(this.currBlockHeight)
   198  	}
   199  }
   200  
   201  func (this *LedgerStoreImp) ContainBlock(blockHash common.Hash) (bool, error) {
   202  	return this.blockStore.ContainBlock(blockHash)
   203  }
   204  func (this *LedgerStoreImp) ContainTx(txHash common.Hash) bool {
   205  	result, _ := this.blockStore.ContainTransaction(txHash)
   206  	return result
   207  }
   208  func (this *LedgerStoreImp) GetBlockByHash(blockHash common.Hash) (*types.Block, error) {
   209  	this.lock.RLock()
   210  	defer this.lock.RUnlock()
   211  	block, err := this.blockStore.GetBlock(blockHash)
   212  	if err != nil {
   213  		return nil, err
   214  	}
   215  	return block, nil
   216  }
   217  
   218  //GetBlockHash return the block hash by block height
   219  func (this *LedgerStoreImp) GetBlockHeaderHashByHeight(height uint64) common.Hash {
   220  	return this.getHeaderIndex(height)
   221  }
   222  
   223  func (this *LedgerStoreImp) GetBlockHeaderByHeight(height uint64) (*types.Header, error) {
   224  	blockHash, err := this.blockStore.GetBlockHash(height)
   225  	if err != nil {
   226  		return nil, err
   227  	}
   228  	return this.blockStore.GetHeader(blockHash)
   229  }
   230  
   231  func (this *LedgerStoreImp) GetBlockHashByHeight(height uint64) (common.Hash, error) {
   232  	this.lock.RLock()
   233  	defer this.lock.RUnlock()
   234  	blockHash, err := this.blockStore.GetBlockHash(height)
   235  	if err != nil {
   236  		return common.Hash{}, err
   237  	}
   238  	return blockHash, err
   239  }
   240  func (this *LedgerStoreImp) GetBlockByHeight(height uint64) (*types.Block, error) {
   241  	this.lock.RLock()
   242  	defer this.lock.RUnlock()
   243  	blockHash, err := this.blockStore.GetBlockHash(height)
   244  	if err != nil {
   245  		return nil, err
   246  	}
   247  	return this.GetBlockByHash(blockHash)
   248  }
   249  
   250  /*func (this *LedgerStoreImp) setCurrentBlock(height uint64, blockHash common.Hash) {
   251  	this.lock.Lock()
   252  	defer this.lock.Unlock()
   253  	this.currBlockHash = blockHash
   254  	this.currBlockHeight = height
   255  	return
   256  }*/
   257  func (this *LedgerStoreImp) setCurrentBlock(header *types.Header) {
   258  	this.lock.Lock()
   259  	defer this.lock.Unlock()
   260  	if this.currBlockHeight < header.Height {
   261  		this.currBlockHash = header.Hash()
   262  		this.currBlockHeight = header.Height
   263  	}
   264  /*	if header.Height%types.HWidth == 0 {
   265  		this.bonusCache[header.Height] = []uint64{
   266  			header.Lv1,
   267  			header.Lv2,
   268  			header.Lv3,
   269  			header.Lv4,
   270  			header.Lv5,
   271  			header.Lv6,
   272  			header.Lv7,
   273  			header.Lv8,
   274  			header.Lv9,
   275  		}
   276  	}*/
   277  	return
   278  }
   279  
   280  //GetCurrentBlock return the current block height, and block hash.
   281  //Current block means the latest block in store.
   282  func (this *LedgerStoreImp) GetCurrentBlock() (uint64, common.Hash) {
   283  	this.lock.RLock()
   284  	defer this.lock.RUnlock()
   285  	return this.currBlockHeight, this.currBlockHash
   286  }
   287  
   288  //GetCurrentBlockHash return the current block hash
   289  func (this *LedgerStoreImp) GetCurrentBlockHash() common.Hash {
   290  	this.lock.RLock()
   291  	defer this.lock.RUnlock()
   292  	return this.currBlockHash
   293  }
   294  
   295  //GetCurrentBlockHeight return the current block height
   296  func (this *LedgerStoreImp) GetCurrentBlockHeight() uint64 {
   297  	this.lock.RLock()
   298  	defer this.lock.RUnlock()
   299  	return this.currBlockHeight
   300  }
   301  func (this *LedgerStoreImp) GetAccount(account common.Address) (*states.AccountState, error) {
   302  	this.lock.RLock()
   303  	defer this.lock.RUnlock()
   304  	return this.accountStore.GetPrev(this.GetCurrentBlockHeight(), account)
   305  }
   306  func (this *LedgerStoreImp) GetAccountByHeight(height uint64, account common.Address) (*states.AccountState, error) {
   307  	this.lock.RLock()
   308  	defer this.lock.RUnlock()
   309  	return this.accountStore.GetPrev(height, account)
   310  }
   311  func (this *LedgerStoreImp) GetLeagueByHeight(height uint64, leagueId common.Address) (*states.LeagueState, error) {
   312  	this.lock.RLock()
   313  	defer this.lock.RUnlock()
   314  	return this.leagueStore.GetPrev(height, leagueId)
   315  }
   316  
   317  /*func (this *LedgerStoreImp) GetMetaData(leagueId common.Address) (rate uint32, creator common.Address, minBox uint64, err error) {
   318  	this.lock.RLock()
   319  	defer this.lock.RUnlock()
   320  	return this.leagueStore.GetMetaData(leagueId)
   321  }*/
   322  func (this *LedgerStoreImp) GetLeagueMemberByHeight(height uint64, leagueId, account common.Address) (*states.LeagueMember, error) {
   323  	this.lock.RLock()
   324  	defer this.lock.RUnlock()
   325  	return this.memberStore.GetPrev(height, leagueId, account)
   326  
   327  }
   328  func (this *LedgerStoreImp) SymbolExists(symbol common.Symbol) error {
   329  	this.lock.RLock()
   330  	defer this.lock.RUnlock()
   331  	return this.leagueStore.SymbolExists(symbol)
   332  }
   333  
   334  func (this *LedgerStoreImp) GetTxByHash(txHash common.Hash) (*types.Transaction, uint64, error) {
   335  	this.lock.RLock()
   336  	defer this.lock.RUnlock()
   337  	return this.blockStore.GetTransaction(txHash)
   338  }
   339  
   340  func (this *LedgerStoreImp) verifyHeader(header *types.Header) error {
   341  	if header.Height == 1 {
   342  		return nil
   343  	}
   344  	prevHeader, err := this.GetHeaderByHash(header.PrevBlockHash)
   345  	if err != nil {
   346  		return err
   347  	}
   348  	if prevHeader == nil {
   349  		return fmt.Errorf("cannot find pre header by blockHash %s", header.PrevBlockHash.String())
   350  	}
   351  	if prevHeader.Height+1 != header.Height {
   352  		return fmt.Errorf("block height is incorrect")
   353  	}
   354  	/*if prevHeader.Timestamp >= header.Timestamp {
   355  		return fmt.Errorf("block timestamp is incorrect")
   356  	}*/
   357  	return nil
   358  }
   359  
   360  func (this *LedgerStoreImp) SaveAll(
   361  	blockInfo *BlockInfo) error {
   362  	if this.isSavingBlock() {
   363  		//hash already saved or is saving
   364  		return nil
   365  	}
   366  	defer this.resetSavingBlock()
   367  	/*wg := new(sync.WaitGroup)
   368  	wg.Add(1)
   369  	go func() {
   370  		this.lvlManager.ReceiveAccountStates(blockInfo.AccountStates, blockInfo.GasDestroy, blockInfo.Height())
   371  		wg.Done()
   372  	}()*/
   373  
   374  	err := this.addBlock(blockInfo.Block)
   375  	if err != nil {
   376  		return fmt.Errorf("saveBlock error %s", err)
   377  	}
   378  	if err = this.addAccountState(blockInfo.AccountStates); err != nil {
   379  
   380  		return fmt.Errorf("saveAccountState error %s", err)
   381  	}
   382  	if err = this.addLeagueMembers(blockInfo.Members); err != nil {
   383  		return fmt.Errorf("saveLeagueMemberState error %s", err)
   384  	}
   385  	if err = this.addLeagueState(blockInfo.LeagueStates); err != nil {
   386  		return fmt.Errorf("saveLeagueState error %s", err)
   387  	}
   388  	if err = this.addBirthCerts(blockInfo.LeagueKVs); err != nil {
   389  		return fmt.Errorf("saveBirthCert error %s", err)
   390  	}
   391  	if err = this.saveReceipts(blockInfo.Receipts); err != nil {
   392  		return fmt.Errorf("saveReceipt error %s", err)
   393  	}
   394  	this.delHeaderCache(blockInfo.Block.Hash())
   395  	this.setCurrentBlock(blockInfo.Block.Header)
   396  
   397  	if actor.ConsensusPid != nil {
   398  		actor.ConsensusPid.Tell(blockInfo.Block)
   399  	}
   400  
   401  	txpoolPid, err := bactor.GetActorPid(bactor.TXPOOLACTOR)
   402  
   403  	if err != nil {
   404  		log.Error("txpoolactor not found")
   405  	} else {
   406  		if blockInfo.Block.Header.Height > 1 {
   407  			hi := bactor.HeightChange{blockInfo.Height()}
   408  			txpoolPid.Tell(hi)
   409  		}
   410  	}
   411  
   412  	radarActor, err := bactor.GetActorPid(bactor.MAINRADARACTOR)
   413  	if err != nil {
   414  		log.Error("radarActor not found")
   415  	} else {
   416  		radarActor.Tell(blockInfo.Height())
   417  	}
   418  	/*	for _, v := range blockInfo.AccountStates {
   419  		fmt.Println("save accountState", v.Address.ToString(), v.Data.Nonce)
   420  	}*/
   421  	log.Info("func storages saveAll", "blockHeight", blockInfo.Block.Header.Height, "txlen", blockInfo.Block.Transactions.Len())
   422  	fmt.Printf("🔆 -----S---A---V---E----A---L---L---  Height:%d TxLen:%d Hash:%s lv1:%d lv2:%d lv3:%d lv4:%d lv5:%d lv6:%d lv7:%d lv8:%d lv9:%d\n",
   423  		blockInfo.Block.Header.Height,
   424  		blockInfo.Block.Transactions.Len(),
   425  		blockInfo.Block.Hash().String(),
   426  		//blockInfo.Block.Header.Lv1, blockInfo.Block.Header.Lv2, blockInfo.Block.Header.Lv3, blockInfo.Block.Header.Lv4, blockInfo.Block.Header.Lv5,
   427  		//blockInfo.Block.Header.Lv6, blockInfo.Block.Header.Lv7, blockInfo.Block.Header.Lv8, blockInfo.Block.Header.Lv9,
   428  	)
   429  
   430  	/*
   431  		if blockInfo.Block.Sigs != nil {
   432  			for _, v := range blockInfo.Block.Sigs.FailerSigs {
   433  				p, _ := GetNode(stars, int(byte2Int(v[0:2])))
   434  				fmt.Println("BlockStore computeFairs", p, byte2Int(v[0:2]))
   435  			}
   436  			for _, v := range blockInfo.Block.Sigs.ProcSigs {
   437  				p, _ := GetNode(stars, int(byte2Int(v[0:2])))
   438  				fmt.Println("BlockStore computeProc", p, byte2Int(v[0:2]))
   439  			}
   440  			for _, v := range blockInfo.Block.Sigs.TimeoutSigs {
   441  				p, _ := GetNode(stars, int(byte2Int(v[0:2])))
   442  				fmt.Println("BlockStore computeTimeout", p, byte2Int(v[0:2]))
   443  			}
   444  		}*/
   445  	//this.Print(blockInfo.Block.Header.Height)
   446  	//wg.Wait()
   447  	return nil
   448  }
   449  func (this *LedgerStoreImp) Print(height uint64) {
   450  	blk, err := this.GetBlockByHeight(height)
   451  	if err != nil {
   452  		fmt.Println("🐷🐷print err", err)
   453  	}
   454  	for k, v := range blk.Transactions {
   455  		if v.TxType == types.TransferEnergy || v.TxType == types.TransferBox {
   456  			fmt.Println("🐼🐼num:", k, ",hash:", v.Hash())
   457  		}
   458  	}
   459  }
   460  
   461  func (this *LedgerStoreImp) isSavingBlock() bool {
   462  	this.lock.Lock()
   463  	defer this.lock.Unlock()
   464  	if !this.savingBlock {
   465  		this.savingBlock = true
   466  		return false
   467  	}
   468  	return true
   469  }
   470  
   471  func (this *LedgerStoreImp) resetSavingBlock() {
   472  	this.lock.Lock()
   473  	defer this.lock.Unlock()
   474  	this.savingBlock = false
   475  }
   476  func (this *LedgerStoreImp) addLeagueMembers(states states.LeagueMembers) error {
   477  	this.memberStore.NewBatch()
   478  	err := this.memberStore.BatchSave(states)
   479  	if err != nil {
   480  		return err
   481  	}
   482  	if err = this.memberStore.CommitTo(); err != nil {
   483  		return err
   484  	}
   485  	return nil
   486  }
   487  func (this *LedgerStoreImp) addLeagueState(states states.LeagueStates) error {
   488  	this.leagueStore.NewBatch()
   489  	err := this.leagueStore.BatchSave(states)
   490  	if err != nil {
   491  		return err
   492  	}
   493  	if err = this.leagueStore.CommitTo(); err != nil {
   494  		return err
   495  	}
   496  	return nil
   497  }
   498  func (this *LedgerStoreImp) addBirthCerts(kvs []*LeagueKV) error {
   499  	this.birthCertStore.NewBatch()
   500  	for _, v := range kvs {
   501  		this.birthCertStore.BatchPutBirthCert(v.K, v.V)
   502  	}
   503  	return this.birthCertStore.CommitTo()
   504  }
   505  func (this *LedgerStoreImp) addAccountState(accountStates states.AccountStates) error {
   506  	this.accountStore.NewBatch()
   507  	err := this.accountStore.BatchSave(accountStates)
   508  	if err != nil {
   509  		return err
   510  	}
   511  	if err = this.accountStore.CommitTo(); err != nil {
   512  		return err
   513  	}
   514  	return nil
   515  }
   516  
   517  func (this *LedgerStoreImp) addBlock(block *types.Block) error {
   518  
   519  	currBlockHeight := this.GetCurrentBlockHeight()
   520  	blockHeight := block.Header.Height
   521  	if blockHeight <= currBlockHeight {
   522  		return fmt.Errorf("The block height is less than the current height")
   523  	}
   524  	nextBlockHeight := currBlockHeight + 1
   525  	if blockHeight != nextBlockHeight {
   526  		return fmt.Errorf("block height %d not equal next block height %d", blockHeight, nextBlockHeight)
   527  	}
   528  	err := this.verifyHeader(block.Header)
   529  	if err != nil {
   530  		return fmt.Errorf("verifyHeader error %s", err)
   531  	}
   532  	return this.saveBlock(block)
   533  }
   534  
   535  func (this *LedgerStoreImp) GetTxHashesByAccount(account common.Address) {
   536  	this.lock.RLock()
   537  	defer this.lock.RUnlock()
   538  
   539  }
   540  func (this *LedgerStoreImp) GetAccountStateHeights(account common.Address) {
   541  
   542  }
   543  
   544  func (this *LedgerStoreImp) GetNextHeaderProperty(height uint64) ([]uint64, error) {
   545  	return this.lvlManager.GetNextHeaderProperty(height)
   546  
   547  }
   548  func (this *LedgerStoreImp) saveBlock(block *types.Block) error {
   549  	blockHash := block.Hash()
   550  	blockHeight := block.Header.Height
   551  	this.blockStore.NewBatch()
   552  	//err := this.saveHeaderIndexList() // 2000高度存一次 暂时考虑废弃
   553  	//if err != nil {
   554  	//	return fmt.Errorf("saveHeaderIndexList error %s", err)
   555  	//}
   556  	var err error
   557  	this.blockStore.SaveBlockHash(blockHeight, blockHash) // 高度-块哈希
   558  	if err = this.blockStore.SaveBlock(block); err != nil {
   559  		return fmt.Errorf("SaveBlock height %d hash %s error %s", blockHeight, blockHash.String(), err)
   560  	}
   561  	err = this.blockStore.CommitTo()
   562  	if err != nil {
   563  		return err
   564  	}
   565  	this.setHeaderIndex(blockHeight, blockHash)
   566  	return nil
   567  }
   568  
   569  func (this *LedgerStoreImp) SaveAccounts(states states.AccountStates) error {
   570  	this.lock.Lock()
   571  	defer this.lock.Unlock()
   572  	this.accountStore.NewBatch()
   573  	err := this.accountStore.BatchSave(states)
   574  	if err != nil {
   575  		return err
   576  	}
   577  	err = this.accountStore.CommitTo()
   578  	return err
   579  }
   580  func (this *LedgerStoreImp) saveReceipts(receipts types.Receipts) error {
   581  	this.receiptStore.NewBatch()
   582  	this.receiptStore.BatchSave(receipts)
   583  	err := this.receiptStore.CommitTo()
   584  	return err
   585  }
   586  func (this *LedgerStoreImp) SaveLeagues(states states.LeagueStates, members states.LeagueMembers) error {
   587  	this.lock.Lock()
   588  	defer this.lock.Unlock()
   589  	this.leagueStore.NewBatch()
   590  	err := this.leagueStore.BatchSave(states)
   591  	if err != nil {
   592  		return err
   593  	}
   594  	if err = this.leagueStore.CommitTo(); err != nil {
   595  		return err
   596  	}
   597  
   598  	this.memberStore.NewBatch()
   599  	if err = this.memberStore.BatchSave(members); err != nil {
   600  		return err
   601  	}
   602  	if err = this.memberStore.CommitTo(); err != nil {
   603  		return err
   604  	}
   605  	return nil
   606  }
   607  
   608  func (this *LedgerStoreImp) GetTxByLeagueId(leagueId common.Address) (*types.Transaction, uint64, error) {
   609  	this.lock.RLock()
   610  	defer this.lock.RUnlock()
   611  	txHash, err := this.birthCertStore.GetBirthCert(leagueId)
   612  	if err != nil {
   613  		return nil, 0, err
   614  	}
   615  	tx, height, err := this.blockStore.GetTransaction(txHash)
   616  	if err != nil {
   617  		return nil, 0, err
   618  	}
   619  	return tx, height, nil
   620  }
   621  func (this *LedgerStoreImp) SaveBlockForMockTest(block *types.Block) error {
   622  	blockHash := block.Hash()
   623  	blockHeight := block.Header.Height
   624  	this.setHeaderIndex(blockHeight, blockHash)
   625  	this.blockStore.NewBatch()
   626  	this.blockStore.SaveBlockHash(blockHeight, blockHash)
   627  	err := this.blockStore.SaveBlock(block)
   628  	if err != nil {
   629  		return fmt.Errorf("SaveBlock height %d hash %s error %s", blockHeight, blockHash.String(), err)
   630  	}
   631  	err = this.blockStore.CommitTo()
   632  	if err != nil {
   633  		return err
   634  	}
   635  	this.delHeaderCache(block.Hash())
   636  	this.setCurrentBlock(block.Header)
   637  	return nil
   638  }
   639  func (this *LedgerStoreImp) SaveBirthCertForMockTest(leagueId common.Address, txHash common.Hash) error {
   640  	this.birthCertStore.NewBatch()
   641  	this.birthCertStore.BatchPutBirthCert(leagueId, txHash)
   642  	err := this.birthCertStore.CommitTo()
   643  	return err
   644  }
   645  
   646  func (this *LedgerStoreImp) GetAccountRange(start, end uint64, account common.Address) (states.AccountStates, error) {
   647  	return this.accountStore.GetAccountRange(start, end, account)
   648  }
   649  func (this *LedgerStoreImp) GetAccountLvlRange(start, end uint64, account common.Address) []common.FTreer {
   650  	return this.lvlManager.LevelStore.GetAccountLvlRange(start, end, account)
   651  }
   652  func (this *LedgerStoreImp) GetAccountLevel(height uint64, account common.Address) account_level.EasyLevel {
   653  	return this.lvlManager.LevelStore.GetAccountLevel(height, account)
   654  }
   655  func (this *LedgerStoreImp) GetBouns() map[uint64][]uint64 {
   656  	return this.bonusCache
   657  }