github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/cmd/fbchaind/mpt/common.go (about)

     1  package mpt
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  
     7  	iavlstore "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/iavl"
     8  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/mpt"
     9  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/rootmulti"
    10  	"github.com/fibonacci-chain/fbc/libs/iavl"
    11  	dbm "github.com/fibonacci-chain/fbc/libs/tm-db"
    12  
    13  	ethcmn "github.com/ethereum/go-ethereum/common"
    14  	ethstate "github.com/ethereum/go-ethereum/core/state"
    15  	"github.com/ethereum/go-ethereum/ethdb"
    16  	"github.com/fibonacci-chain/fbc/app"
    17  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/server"
    18  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    19  	authtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/types"
    20  	tmdb "github.com/fibonacci-chain/fbc/libs/tm-db"
    21  	evmtypes "github.com/fibonacci-chain/fbc/x/evm/types"
    22  )
    23  
    24  const (
    25  	applicationDB = "application"
    26  
    27  	accStoreKey    = authtypes.StoreKey
    28  	evmStoreKey    = evmtypes.StoreKey
    29  	legacyStoreKey = "evmlegacy"
    30  
    31  	iavlAccKey       = "s/k:acc/"
    32  	iavlEvmKey       = "s/k:evm/"
    33  	iavlEvmLegacyKey = "s/k:evmlegacy/"
    34  	KeyParams        = "s/k:params/"
    35  )
    36  
    37  func panicError(err error) {
    38  	if err != nil {
    39  		panic(err)
    40  	}
    41  }
    42  
    43  // checkValidKey checks if the key is equal to authtypes.StoreKey or evmtypes.StoreKey
    44  func checkValidKey(key string) error {
    45  	if key != accStoreKey && key != evmStoreKey && key != legacyStoreKey {
    46  		return fmt.Errorf("invalid key %s", key)
    47  	}
    48  	return nil
    49  }
    50  
    51  /*
    52   * Common functions about cosmos-sdk
    53   */
    54  // newMigrationApp generates a new app with the given key and application.db
    55  func newMigrationApp(ctx *server.Context) *app.FBChainApp {
    56  	appDb := openApplicationDb(ctx.Config.RootDir)
    57  	return app.NewFBChainApp(
    58  		ctx.Logger,
    59  		appDb,
    60  		nil,
    61  		true,
    62  		map[int64]bool{},
    63  		0,
    64  	)
    65  }
    66  
    67  func openApplicationDb(rootdir string) tmdb.DB {
    68  	dataDir := filepath.Join(rootdir, "data")
    69  	appDb, err := sdk.NewDB(applicationDB, dataDir)
    70  	if err != nil {
    71  		panic("fail to open application db: " + err.Error())
    72  	}
    73  	return appDb
    74  }
    75  
    76  /*
    77   * Common functions about mpt
    78   */
    79  // getStorageTrie returns the trie of the given address and stateRoot
    80  func getStorageTrie(db ethstate.Database, addrHash, stateRoot ethcmn.Hash) ethstate.Trie {
    81  	tr, err := db.OpenStorageTrie(addrHash, stateRoot)
    82  	panicError(err)
    83  	return tr
    84  }
    85  
    86  // pushData2Database commit the data to the database
    87  func pushData2Database(db ethstate.Database, trie ethstate.Trie, height int64, isEvm bool) {
    88  	var storageRoot ethcmn.Hash
    89  	root, err := trie.Commit(func(_ [][]byte, _ []byte, leaf []byte, parent ethcmn.Hash) error {
    90  		storageRoot.SetBytes(leaf)
    91  		if storageRoot != mpt.EmptyRootHash {
    92  			db.TrieDB().Reference(storageRoot, parent)
    93  		}
    94  		return nil
    95  	})
    96  	panicError(err)
    97  
    98  	err = db.TrieDB().Commit(root, false, nil)
    99  	panicError(err)
   100  
   101  	setMptRootHash(db, uint64(height), root, isEvm)
   102  }
   103  
   104  // setMptRootHash sets the mapping from block height to root mpt hash
   105  func setMptRootHash(db ethstate.Database, height uint64, hash ethcmn.Hash, isEvm bool) {
   106  	heightBytes := sdk.Uint64ToBigEndian(height)
   107  	if isEvm {
   108  		db.TrieDB().DiskDB().Put(mpt.KeyPrefixEvmLatestStoredHeight, heightBytes)
   109  		db.TrieDB().DiskDB().Put(append(mpt.KeyPrefixEvmRootMptHash, heightBytes...), hash.Bytes())
   110  	} else {
   111  		db.TrieDB().DiskDB().Put(mpt.KeyPrefixAccLatestStoredHeight, heightBytes)
   112  		db.TrieDB().DiskDB().Put(append(mpt.KeyPrefixAccRootMptHash, heightBytes...), hash.Bytes())
   113  	}
   114  }
   115  
   116  func writeDataToRawdb(batch ethdb.Batch) {
   117  	if err := batch.Write(); err != nil {
   118  		panic(err)
   119  	}
   120  	batch.Reset()
   121  }
   122  
   123  func getUpgradedTree(db dbm.DB, prefix []byte, usePreLatest bool) *iavl.MutableTree {
   124  	rs := rootmulti.NewStore(db)
   125  	latestVersion := rs.GetLatestVersion()
   126  	if latestVersion == 0 {
   127  		return nil
   128  	}
   129  
   130  	db = dbm.NewPrefixDB(db, prefix)
   131  
   132  	tree, err := iavl.NewMutableTree(db, iavlstore.IavlCacheSize)
   133  	if err != nil {
   134  		panic("Fail to get tree: " + err.Error())
   135  	}
   136  
   137  	if usePreLatest {
   138  		latestVersion -= 1
   139  	}
   140  
   141  	if latestVersion <= 0 {
   142  		panic(fmt.Sprintf("invalid version to load: %d", latestVersion))
   143  	}
   144  
   145  	_, err = tree.LoadVersion(latestVersion)
   146  	if err != nil {
   147  		panic("fail to load target version tree: " + err.Error())
   148  	}
   149  
   150  	return tree
   151  }